├── .editorconfig ├── .env.example ├── .gitattributes ├── .gitignore ├── .htaccess ├── .styleci.yml ├── LICENSE.md ├── README.md ├── app ├── Console │ └── Kernel.php ├── Exceptions │ └── Handler.php ├── Http │ ├── Controllers │ │ ├── Auth │ │ │ ├── ConfirmPasswordController.php │ │ │ ├── ForgotPasswordController.php │ │ │ ├── LoginController.php │ │ │ ├── RegisterController.php │ │ │ ├── ResetPasswordController.php │ │ │ └── VerificationController.php │ │ ├── CentrePointController.php │ │ ├── Controller.php │ │ ├── DataController.php │ │ ├── HomeController.php │ │ ├── MapController.php │ │ └── SpaceController.php │ ├── Kernel.php │ └── Middleware │ │ ├── Authenticate.php │ │ ├── EncryptCookies.php │ │ ├── PreventRequestsDuringMaintenance.php │ │ ├── RedirectIfAuthenticated.php │ │ ├── TrimStrings.php │ │ ├── TrustHosts.php │ │ ├── TrustProxies.php │ │ └── VerifyCsrfToken.php ├── Models │ ├── CentrePoint.php │ ├── Space.php │ └── User.php └── Providers │ ├── AppServiceProvider.php │ ├── AuthServiceProvider.php │ ├── BroadcastServiceProvider.php │ ├── EventServiceProvider.php │ └── RouteServiceProvider.php ├── artisan ├── bootstrap ├── app.php └── cache │ └── .gitignore ├── composer.json ├── composer.lock ├── config ├── app.php ├── auth.php ├── broadcasting.php ├── cache.php ├── cors.php ├── database.php ├── datatables.php ├── filesystems.php ├── hashing.php ├── logging.php ├── mail.php ├── queue.php ├── sanctum.php ├── services.php ├── session.php └── view.php ├── database ├── .gitignore ├── factories │ └── UserFactory.php ├── migrations │ ├── 2014_10_12_000000_create_users_table.php │ ├── 2014_10_12_100000_create_password_resets_table.php │ ├── 2019_08_19_000000_create_failed_jobs_table.php │ ├── 2019_12_14_000001_create_personal_access_tokens_table.php │ ├── 2022_05_09_062500_create_spaces_table.php │ └── 2022_05_12_052741_create_centre_points_table.php └── seeders │ └── DatabaseSeeder.php ├── lang └── en │ ├── auth.php │ ├── pagination.php │ ├── passwords.php │ └── validation.php ├── package-lock.json ├── package.json ├── phpunit.xml ├── public ├── .htaccess ├── assets │ └── sweetalert2 │ │ ├── LICENSE │ │ ├── README.md │ │ ├── dist │ │ ├── sweetalert2.all.js │ │ ├── sweetalert2.all.min.js │ │ ├── sweetalert2.css │ │ ├── sweetalert2.js │ │ ├── sweetalert2.min.css │ │ └── sweetalert2.min.js │ │ ├── package.json │ │ ├── src │ │ ├── SweetAlert.js │ │ ├── constants.js │ │ ├── globalState.js │ │ ├── instanceMethods.js │ │ ├── instanceMethods │ │ │ ├── _destroy.js │ │ │ ├── _main.js │ │ │ ├── buttons-handlers.js │ │ │ ├── close.js │ │ │ ├── enable-disable-elements.js │ │ │ ├── getInput.js │ │ │ ├── hideLoading.js │ │ │ ├── keydown-handler.js │ │ │ ├── popup-click-handler.js │ │ │ ├── progress-steps.js │ │ │ ├── show-reset-validation-error.js │ │ │ └── update.js │ │ ├── privateMethods.js │ │ ├── privateProps.js │ │ ├── scss │ │ │ ├── _animations.scss │ │ │ ├── _body.scss │ │ │ ├── _core.scss │ │ │ ├── _mixins.scss │ │ │ ├── _polyfills.scss │ │ │ ├── _theming.scss │ │ │ ├── _toasts-animations.scss │ │ │ ├── _toasts-body.scss │ │ │ └── _toasts.scss │ │ ├── staticMethods.js │ │ ├── staticMethods │ │ │ ├── argsToParams.js │ │ │ ├── dom.js │ │ │ ├── fire.js │ │ │ ├── mixin.js │ │ │ ├── queue.js │ │ │ ├── showLoading.js │ │ │ └── timer.js │ │ ├── sweetalert2.css │ │ ├── sweetalert2.css.map │ │ ├── sweetalert2.js │ │ ├── sweetalert2.scss │ │ ├── utils │ │ │ ├── DismissReason.js │ │ │ ├── Timer.js │ │ │ ├── aria.js │ │ │ ├── classes.js │ │ │ ├── defaultInputValidators.js │ │ │ ├── dom │ │ │ │ ├── animationEndEvent.js │ │ │ │ ├── domUtils.js │ │ │ │ ├── getters.js │ │ │ │ ├── index.js │ │ │ │ ├── init.js │ │ │ │ ├── inputUtils.js │ │ │ │ ├── measureScrollbar.js │ │ │ │ ├── parseHtmlToContainer.js │ │ │ │ └── renderers │ │ │ │ │ ├── render.js │ │ │ │ │ ├── renderActions.js │ │ │ │ │ ├── renderCloseButton.js │ │ │ │ │ ├── renderContainer.js │ │ │ │ │ ├── renderContent.js │ │ │ │ │ ├── renderFooter.js │ │ │ │ │ ├── renderHeader.js │ │ │ │ │ ├── renderIcon.js │ │ │ │ │ ├── renderImage.js │ │ │ │ │ ├── renderInput.js │ │ │ │ │ ├── renderPopup.js │ │ │ │ │ ├── renderProgressSteps.js │ │ │ │ │ └── renderTitle.js │ │ │ ├── ieFix.js │ │ │ ├── iosFix.js │ │ │ ├── isNodeEnv.js │ │ │ ├── openPopup.js │ │ │ ├── params.js │ │ │ ├── scrollbarFix.js │ │ │ ├── setParameters.js │ │ │ └── utils.js │ │ ├── variables.css │ │ ├── variables.css.map │ │ └── variables.scss │ │ └── sweetalert2.d.ts ├── css │ └── app.css ├── favicon.ico ├── index.php ├── js │ └── app.js ├── mix-manifest.json └── robots.txt ├── resources ├── css │ └── app.css ├── js │ ├── app.js │ └── bootstrap.js ├── sass │ ├── _variables.scss │ └── app.scss └── views │ ├── auth │ ├── login.blade.php │ ├── passwords │ │ ├── confirm.blade.php │ │ ├── email.blade.php │ │ └── reset.blade.php │ ├── register.blade.php │ └── verify.blade.php │ ├── centrepoint │ ├── action.blade.php │ ├── create.blade.php │ ├── edit.blade.php │ └── index.blade.php │ ├── detail.blade.php │ ├── home.blade.php │ ├── layouts │ └── app.blade.php │ ├── map.blade.php │ ├── space │ ├── action.blade.php │ ├── create.blade.php │ ├── edit.blade.php │ └── index.blade.php │ └── welcome.blade.php ├── routes ├── api.php ├── channels.php ├── console.php └── web.php ├── storage ├── app │ ├── .gitignore │ └── public │ │ └── .gitignore ├── framework │ ├── .gitignore │ ├── cache │ │ ├── .gitignore │ │ └── data │ │ │ └── .gitignore │ ├── sessions │ │ └── .gitignore │ ├── testing │ │ └── .gitignore │ └── views │ │ └── .gitignore └── logs │ └── .gitignore ├── tests ├── CreatesApplication.php ├── Feature │ └── ExampleTest.php ├── TestCase.php └── Unit │ └── ExampleTest.php └── webpack.mix.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | indent_style = space 8 | indent_size = 4 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | 14 | [*.{yml,yaml}] 15 | indent_size = 2 16 | 17 | [docker-compose.yml] 18 | indent_size = 4 19 | -------------------------------------------------------------------------------- /.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 | LOG_DEPRECATIONS_CHANNEL=null 9 | LOG_LEVEL=debug 10 | 11 | DB_CONNECTION=mysql 12 | DB_HOST=127.0.0.1 13 | DB_PORT=3306 14 | DB_DATABASE=laravel 15 | DB_USERNAME=root 16 | DB_PASSWORD= 17 | 18 | BROADCAST_DRIVER=log 19 | CACHE_DRIVER=file 20 | FILESYSTEM_DISK=local 21 | QUEUE_CONNECTION=sync 22 | SESSION_DRIVER=file 23 | SESSION_LIFETIME=120 24 | 25 | MEMCACHED_HOST=127.0.0.1 26 | 27 | REDIS_HOST=127.0.0.1 28 | REDIS_PASSWORD=null 29 | REDIS_PORT=6379 30 | 31 | MAIL_MAILER=smtp 32 | MAIL_HOST=mailhog 33 | MAIL_PORT=1025 34 | MAIL_USERNAME=null 35 | MAIL_PASSWORD=null 36 | MAIL_ENCRYPTION=null 37 | MAIL_FROM_ADDRESS="hello@example.com" 38 | MAIL_FROM_NAME="${APP_NAME}" 39 | 40 | AWS_ACCESS_KEY_ID= 41 | AWS_SECRET_ACCESS_KEY= 42 | AWS_DEFAULT_REGION=us-east-1 43 | AWS_BUCKET= 44 | AWS_USE_PATH_STYLE_ENDPOINT=false 45 | 46 | PUSHER_APP_ID= 47 | PUSHER_APP_KEY= 48 | PUSHER_APP_SECRET= 49 | PUSHER_APP_CLUSTER=mt1 50 | 51 | MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" 52 | MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" 53 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | 3 | *.blade.php diff=html 4 | *.css diff=css 5 | *.html diff=html 6 | *.md diff=markdown 7 | *.php diff=php 8 | 9 | /.github export-ignore 10 | CHANGELOG.md export-ignore 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /public/hot 3 | /public/storage 4 | /storage/*.key 5 | /vendor 6 | .env 7 | .env.backup 8 | .phpunit.result.cache 9 | Homestead.json 10 | Homestead.yaml 11 | npm-debug.log 12 | yarn-error.log 13 | /.idea 14 | /.vscode 15 | -------------------------------------------------------------------------------- /.htaccess: -------------------------------------------------------------------------------- 1 | 2 | RewriteEngine on 3 | RewriteRule ^$ public/ [L] 4 | RewriteRule (.*) public/$1 [L] 5 | -------------------------------------------------------------------------------- /.styleci.yml: -------------------------------------------------------------------------------- 1 | php: 2 | preset: laravel 3 | disabled: 4 | - no_unused_imports 5 | finder: 6 | not-name: 7 | - index.php 8 | js: 9 | finder: 10 | not-name: 11 | - webpack.mix.js 12 | css: true 13 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Eri Pratama 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | Build Status 5 | Total Downloads 6 | Latest Stable Version 7 | License 8 |

9 | 10 | ## About Laravel 11 | 12 | Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Laravel takes the pain out of development by easing common tasks used in many web projects, such as: 13 | 14 | - [Simple, fast routing engine](https://laravel.com/docs/routing). 15 | - [Powerful dependency injection container](https://laravel.com/docs/container). 16 | - Multiple back-ends for [session](https://laravel.com/docs/session) and [cache](https://laravel.com/docs/cache) storage. 17 | - Expressive, intuitive [database ORM](https://laravel.com/docs/eloquent). 18 | - Database agnostic [schema migrations](https://laravel.com/docs/migrations). 19 | - [Robust background job processing](https://laravel.com/docs/queues). 20 | - [Real-time event broadcasting](https://laravel.com/docs/broadcasting). 21 | 22 | Laravel is accessible, powerful, and provides tools required for large, robust applications. 23 | 24 | ## Learning Laravel 25 | 26 | Laravel has the most extensive and thorough [documentation](https://laravel.com/docs) and video tutorial library of all modern web application frameworks, making it a breeze to get started with the framework. 27 | 28 | If you don't feel like reading, [Laracasts](https://laracasts.com) can help. Laracasts contains over 2000 video tutorials on a range of topics including Laravel, modern PHP, unit testing, and JavaScript. Boost your skills by digging into our comprehensive video library. 29 | 30 | ## Laravel Sponsors 31 | 32 | We would like to extend our thanks to the following sponsors for funding Laravel development. If you are interested in becoming a sponsor, please visit the Laravel [Patreon page](https://patreon.com/taylorotwell). 33 | 34 | ### Premium Partners 35 | 36 | - **[Vehikl](https://vehikl.com/)** 37 | - **[Tighten Co.](https://tighten.co)** 38 | - **[Kirschbaum Development Group](https://kirschbaumdevelopment.com)** 39 | - **[64 Robots](https://64robots.com)** 40 | - **[Cubet Techno Labs](https://cubettech.com)** 41 | - **[Cyber-Duck](https://cyber-duck.co.uk)** 42 | - **[Many](https://www.many.co.uk)** 43 | - **[Webdock, Fast VPS Hosting](https://www.webdock.io/en)** 44 | - **[DevSquad](https://devsquad.com)** 45 | - **[Curotec](https://www.curotec.com/services/technologies/laravel/)** 46 | - **[OP.GG](https://op.gg)** 47 | - **[WebReinvent](https://webreinvent.com/?utm_source=laravel&utm_medium=github&utm_campaign=patreon-sponsors)** 48 | - **[Lendio](https://lendio.com)** 49 | 50 | ## Contributing 51 | 52 | Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions). 53 | 54 | ## Code of Conduct 55 | 56 | In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct). 57 | 58 | ## Security Vulnerabilities 59 | 60 | If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell via [taylor@laravel.com](mailto:taylor@laravel.com). All security vulnerabilities will be promptly addressed. 61 | 62 | ## License 63 | 64 | The Laravel framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). 65 | -------------------------------------------------------------------------------- /app/Console/Kernel.php: -------------------------------------------------------------------------------- 1 | command('inspire')->hourly(); 19 | } 20 | 21 | /** 22 | * Register the commands for the application. 23 | * 24 | * @return void 25 | */ 26 | protected function commands() 27 | { 28 | $this->load(__DIR__.'/Commands'); 29 | 30 | require base_path('routes/console.php'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/Exceptions/Handler.php: -------------------------------------------------------------------------------- 1 | , \Psr\Log\LogLevel::*> 14 | */ 15 | protected $levels = [ 16 | // 17 | ]; 18 | 19 | /** 20 | * A list of the exception types that are not reported. 21 | * 22 | * @var array> 23 | */ 24 | protected $dontReport = [ 25 | // 26 | ]; 27 | 28 | /** 29 | * A list of the inputs that are never flashed for validation exceptions. 30 | * 31 | * @var array 32 | */ 33 | protected $dontFlash = [ 34 | 'current_password', 35 | 'password', 36 | 'password_confirmation', 37 | ]; 38 | 39 | /** 40 | * Register the exception handling callbacks for the application. 41 | * 42 | * @return void 43 | */ 44 | public function register() 45 | { 46 | $this->reportable(function (Throwable $e) { 47 | // 48 | }); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /app/Http/Controllers/Auth/ConfirmPasswordController.php: -------------------------------------------------------------------------------- 1 | middleware('auth'); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/Http/Controllers/Auth/ForgotPasswordController.php: -------------------------------------------------------------------------------- 1 | middleware('guest')->except('logout'); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/Http/Controllers/Auth/RegisterController.php: -------------------------------------------------------------------------------- 1 | middleware('guest'); 42 | } 43 | 44 | /** 45 | * Get a validator for an incoming registration request. 46 | * 47 | * @param array $data 48 | * @return \Illuminate\Contracts\Validation\Validator 49 | */ 50 | protected function validator(array $data) 51 | { 52 | return Validator::make($data, [ 53 | 'name' => ['required', 'string', 'max:255'], 54 | 'email' => ['required', 'string', 'email', 'max:255', 'unique:users'], 55 | 'password' => ['required', 'string', 'min:8', 'confirmed'], 56 | ]); 57 | } 58 | 59 | /** 60 | * Create a new user instance after a valid registration. 61 | * 62 | * @param array $data 63 | * @return \App\Models\User 64 | */ 65 | protected function create(array $data) 66 | { 67 | return User::create([ 68 | 'name' => $data['name'], 69 | 'email' => $data['email'], 70 | 'password' => Hash::make($data['password']), 71 | ]); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /app/Http/Controllers/Auth/ResetPasswordController.php: -------------------------------------------------------------------------------- 1 | middleware('auth'); 39 | $this->middleware('signed')->only('verify'); 40 | $this->middleware('throttle:6,1')->only('verify', 'resend'); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/Http/Controllers/CentrePointController.php: -------------------------------------------------------------------------------- 1 | route('centre-point.index') 39 | ->with('success', 'Hanya bisa input 1 data centre point saja, silahkan hapus data sebelumnya untuk koordinat baru'); 40 | } 41 | } 42 | 43 | /** 44 | * Store a newly created resource in storage. 45 | * 46 | * @param \Illuminate\Http\Request $request 47 | * @return \Illuminate\Http\Response 48 | */ 49 | public function store(Request $request) 50 | { 51 | // Lakukan validasi data 52 | $this->validate($request,[ 53 | 'location' => 'required' 54 | ]); 55 | 56 | // jalankan proses simpan data ke table centrepoint 57 | $centrePoint = new CentrePoint; 58 | $centrePoint->location = $request->input('location'); 59 | $centrePoint->save(); 60 | 61 | // setelah data disimpan redirect ke halaman index centrepoint 62 | if ($centrePoint) { 63 | return redirect()->route('centre-point.index')->with('success', 'Data berhasil Disimpan'); 64 | } else { 65 | return redirect()->route('centre-point.index')->with('error', 'Data gagal Disimpan'); 66 | } 67 | } 68 | 69 | /** 70 | * Display the specified resource. 71 | * 72 | * @param int $id 73 | * @return \Illuminate\Http\Response 74 | */ 75 | public function show($id) 76 | { 77 | // 78 | } 79 | 80 | /** 81 | * Show the form for editing the specified resource. 82 | * 83 | * @param int $id 84 | * @return \Illuminate\Http\Response 85 | */ 86 | public function edit(CentrePoint $centrePoint) 87 | { 88 | // Mencari data yang dipilih lalu menampilkannya ke view edit centrepoint 89 | // dan mempassing $centrePoint ke view edit centrepoint 90 | $centrePoint = CentrePoint::findOrFail($centrePoint->id); 91 | return view('centrepoint.edit',[ 92 | 'centrePoint' => $centrePoint 93 | ]); 94 | } 95 | 96 | /** 97 | * Update the specified resource in storage. 98 | * 99 | * @param \Illuminate\Http\Request $request 100 | * @param int $id 101 | * @return \Illuminate\Http\Response 102 | */ 103 | public function update(Request $request, CentrePoint $centrePoint) 104 | { 105 | // setelah data centrepoint yang akan di edit sesuai 106 | // maka jalankan proses update jika berhasil akan di redirect ke halaman index 107 | $centrePoint = CentrePoint::findOrFail($centrePoint->id); 108 | $centrePoint->location = $request->input('location'); 109 | $centrePoint->update(); 110 | 111 | if ($centrePoint) { 112 | return redirect()->route('centre-point.index')->with('success', 'Data berhasil Diupdate'); 113 | } else { 114 | return redirect()->route('centre-point.index')->with('error', 'Data gagal Diupdate'); 115 | } 116 | } 117 | 118 | /** 119 | * Remove the specified resource from storage. 120 | * 121 | * @param int $id 122 | * @return \Illuminate\Http\Response 123 | */ 124 | public function destroy($id) 125 | { 126 | // Proses hapus data dari tabel centrepoint 127 | $centrePoint = CentrePoint::findOrFail($id); 128 | $centrePoint->delete(); 129 | return redirect()->back(); 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /app/Http/Controllers/Controller.php: -------------------------------------------------------------------------------- 1 | of($centrepoint) 20 | ->addColumn('action', 'centrepoint.action') 21 | ->addIndexColumn() 22 | ->rawColumns(['action']) 23 | ->toJson(); 24 | } 25 | 26 | public function spaces() 27 | { 28 | // Method ini untuk menampilkan data dari tabel spaces 29 | // ke dalam datatables kita juga menambahkan column untuk menampilkan button 30 | // action 31 | $spaces = Space::orderBy('created_at','DESC'); 32 | return datatables()->of($spaces) 33 | ->addColumn('action','space.action') 34 | ->addIndexColumn() 35 | ->rawColumns(['action']) 36 | ->toJson(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/Http/Controllers/HomeController.php: -------------------------------------------------------------------------------- 1 | middleware('auth'); 17 | } 18 | 19 | /** 20 | * Show the application dashboard. 21 | * 22 | * @return \Illuminate\Contracts\Support\Renderable 23 | */ 24 | public function index() 25 | { 26 | return view('home'); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/Http/Controllers/MapController.php: -------------------------------------------------------------------------------- 1 | first(); 19 | $spaces = Space::get(); 20 | return view('map',[ 21 | 'spaces' => $spaces, 22 | 'centrePoint' => $centrePoint 23 | ]); 24 | //return dd($spaces); 25 | } 26 | 27 | public function show($slug) 28 | { 29 | /** 30 | * Hampir sama dengam method index diatas 31 | * tapi disini kita hanya akan menampilkan single data saja untuk space 32 | * yang kita pilih pada view map dan selanjutnya kita akan di arahkan 33 | * ke halaman detail untuk melihat informasi lebih lengkap dari space 34 | * yang kita pilih 35 | */ 36 | $centrePoint = CentrePoint::get()->first(); 37 | $spaces = Space::where('slug',$slug)->first(); 38 | return view('detail',[ 39 | 'centrePoint' => $centrePoint, 40 | 'spaces' => $spaces 41 | ]); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/Http/Kernel.php: -------------------------------------------------------------------------------- 1 | 15 | */ 16 | protected $middleware = [ 17 | // \App\Http\Middleware\TrustHosts::class, 18 | \App\Http\Middleware\TrustProxies::class, 19 | \Illuminate\Http\Middleware\HandleCors::class, 20 | \App\Http\Middleware\PreventRequestsDuringMaintenance::class, 21 | \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class, 22 | \App\Http\Middleware\TrimStrings::class, 23 | \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, 24 | ]; 25 | 26 | /** 27 | * The application's route middleware groups. 28 | * 29 | * @var array> 30 | */ 31 | protected $middlewareGroups = [ 32 | 'web' => [ 33 | \App\Http\Middleware\EncryptCookies::class, 34 | \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, 35 | \Illuminate\Session\Middleware\StartSession::class, 36 | \Illuminate\View\Middleware\ShareErrorsFromSession::class, 37 | \App\Http\Middleware\VerifyCsrfToken::class, 38 | \Illuminate\Routing\Middleware\SubstituteBindings::class, 39 | ], 40 | 41 | 'api' => [ 42 | // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, 43 | 'throttle:api', 44 | \Illuminate\Routing\Middleware\SubstituteBindings::class, 45 | ], 46 | ]; 47 | 48 | /** 49 | * The application's route middleware. 50 | * 51 | * These middleware may be assigned to groups or used individually. 52 | * 53 | * @var array 54 | */ 55 | protected $routeMiddleware = [ 56 | 'auth' => \App\Http\Middleware\Authenticate::class, 57 | 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, 58 | 'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class, 59 | 'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class, 60 | 'can' => \Illuminate\Auth\Middleware\Authorize::class, 61 | 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, 62 | 'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class, 63 | 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, 64 | 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 65 | 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, 66 | ]; 67 | } 68 | -------------------------------------------------------------------------------- /app/Http/Middleware/Authenticate.php: -------------------------------------------------------------------------------- 1 | expectsJson()) { 18 | return route('login'); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/Http/Middleware/EncryptCookies.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /app/Http/Middleware/PreventRequestsDuringMaintenance.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /app/Http/Middleware/RedirectIfAuthenticated.php: -------------------------------------------------------------------------------- 1 | check()) { 26 | return redirect(RouteServiceProvider::HOME); 27 | } 28 | } 29 | 30 | return $next($request); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/Http/Middleware/TrimStrings.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | 'current_password', 16 | 'password', 17 | 'password_confirmation', 18 | ]; 19 | } 20 | -------------------------------------------------------------------------------- /app/Http/Middleware/TrustHosts.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | public function hosts() 15 | { 16 | return [ 17 | $this->allSubdomainsOfApplicationUrl(), 18 | ]; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/Http/Middleware/TrustProxies.php: -------------------------------------------------------------------------------- 1 | |string|null 14 | */ 15 | protected $proxies; 16 | 17 | /** 18 | * The headers that should be used to detect proxies. 19 | * 20 | * @var int 21 | */ 22 | protected $headers = 23 | Request::HEADER_X_FORWARDED_FOR | 24 | Request::HEADER_X_FORWARDED_HOST | 25 | Request::HEADER_X_FORWARDED_PORT | 26 | Request::HEADER_X_FORWARDED_PROTO | 27 | Request::HEADER_X_FORWARDED_AWS_ELB; 28 | } 29 | -------------------------------------------------------------------------------- /app/Http/Middleware/VerifyCsrfToken.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /app/Models/CentrePoint.php: -------------------------------------------------------------------------------- 1 | image, 0, 5) == "https") { 17 | return $this->image; 18 | } 19 | 20 | if ($this->image) { 21 | return asset('/uploads/imgCover/' . $this->image); 22 | } 23 | 24 | return 'https://via.placeholder.com/500x500.png?text=No+Cover'; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Models/User.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | protected $fillable = [ 21 | 'name', 22 | 'email', 23 | 'password', 24 | ]; 25 | 26 | /** 27 | * The attributes that should be hidden for serialization. 28 | * 29 | * @var array 30 | */ 31 | protected $hidden = [ 32 | 'password', 33 | 'remember_token', 34 | ]; 35 | 36 | /** 37 | * The attributes that should be cast. 38 | * 39 | * @var array 40 | */ 41 | protected $casts = [ 42 | 'email_verified_at' => 'datetime', 43 | ]; 44 | } 45 | -------------------------------------------------------------------------------- /app/Providers/AppServiceProvider.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | protected $policies = [ 16 | // 'App\Models\Model' => 'App\Policies\ModelPolicy', 17 | ]; 18 | 19 | /** 20 | * Register any authentication / authorization services. 21 | * 22 | * @return void 23 | */ 24 | public function boot() 25 | { 26 | $this->registerPolicies(); 27 | 28 | // 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/Providers/BroadcastServiceProvider.php: -------------------------------------------------------------------------------- 1 | > 16 | */ 17 | protected $listen = [ 18 | Registered::class => [ 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 | // 31 | } 32 | 33 | /** 34 | * Determine if events and listeners should be automatically discovered. 35 | * 36 | * @return bool 37 | */ 38 | public function shouldDiscoverEvents() 39 | { 40 | return false; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/Providers/RouteServiceProvider.php: -------------------------------------------------------------------------------- 1 | configureRateLimiting(); 30 | 31 | $this->routes(function () { 32 | Route::middleware('api') 33 | ->prefix('api') 34 | ->group(base_path('routes/api.php')); 35 | 36 | Route::middleware('web') 37 | ->group(base_path('routes/web.php')); 38 | }); 39 | } 40 | 41 | /** 42 | * Configure the rate limiters for the application. 43 | * 44 | * @return void 45 | */ 46 | protected function configureRateLimiting() 47 | { 48 | RateLimiter::for('api', function (Request $request) { 49 | return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip()); 50 | }); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /artisan: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | make(Illuminate\Contracts\Console\Kernel::class); 34 | 35 | $status = $kernel->handle( 36 | $input = new Symfony\Component\Console\Input\ArgvInput, 37 | new Symfony\Component\Console\Output\ConsoleOutput 38 | ); 39 | 40 | /* 41 | |-------------------------------------------------------------------------- 42 | | Shutdown The Application 43 | |-------------------------------------------------------------------------- 44 | | 45 | | Once Artisan has finished running, we will fire off the shutdown events 46 | | so that any final work may be done by the application before we shut 47 | | down the process. This is the last thing to happen to the request. 48 | | 49 | */ 50 | 51 | $kernel->terminate($input, $status); 52 | 53 | exit($status); 54 | -------------------------------------------------------------------------------- /bootstrap/app.php: -------------------------------------------------------------------------------- 1 | singleton( 30 | Illuminate\Contracts\Http\Kernel::class, 31 | App\Http\Kernel::class 32 | ); 33 | 34 | $app->singleton( 35 | Illuminate\Contracts\Console\Kernel::class, 36 | App\Console\Kernel::class 37 | ); 38 | 39 | $app->singleton( 40 | Illuminate\Contracts\Debug\ExceptionHandler::class, 41 | App\Exceptions\Handler::class 42 | ); 43 | 44 | /* 45 | |-------------------------------------------------------------------------- 46 | | Return The Application 47 | |-------------------------------------------------------------------------- 48 | | 49 | | This script returns the application instance. The instance is given to 50 | | the calling script so we can separate the building of the instances 51 | | from the actual running of the application and sending responses. 52 | | 53 | */ 54 | 55 | return $app; 56 | -------------------------------------------------------------------------------- /bootstrap/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "laravel/laravel", 3 | "type": "project", 4 | "description": "The Laravel Framework.", 5 | "keywords": ["framework", "laravel"], 6 | "license": "MIT", 7 | "require": { 8 | "php": "^8.0.2", 9 | "cloudinary-labs/cloudinary-laravel": "^2.0", 10 | "guzzlehttp/guzzle": "^7.2", 11 | "laravel/framework": "^9.11", 12 | "laravel/helpers": "^1.5", 13 | "laravel/sanctum": "^2.14.1", 14 | "laravel/tinker": "^2.7", 15 | "laravel/ui": "^3.4", 16 | "yajra/laravel-datatables-oracle": "~9.0" 17 | }, 18 | "require-dev": { 19 | "fakerphp/faker": "^1.9.1", 20 | "laravel/sail": "^1.0.1", 21 | "mockery/mockery": "^1.4.4", 22 | "nunomaduro/collision": "^6.1", 23 | "phpunit/phpunit": "^9.5.10", 24 | "spatie/laravel-ignition": "^1.0" 25 | }, 26 | "autoload": { 27 | "psr-4": { 28 | "App\\": "app/", 29 | "Database\\Factories\\": "database/factories/", 30 | "Database\\Seeders\\": "database/seeders/" 31 | } 32 | }, 33 | "autoload-dev": { 34 | "psr-4": { 35 | "Tests\\": "tests/" 36 | } 37 | }, 38 | "scripts": { 39 | "post-autoload-dump": [ 40 | "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump", 41 | "@php artisan package:discover --ansi" 42 | ], 43 | "post-update-cmd": [ 44 | "@php artisan vendor:publish --tag=laravel-assets --ansi --force" 45 | ], 46 | "post-root-package-install": [ 47 | "@php -r \"file_exists('.env') || copy('.env.example', '.env');\"" 48 | ], 49 | "post-create-project-cmd": [ 50 | "@php artisan key:generate --ansi" 51 | ] 52 | }, 53 | "extra": { 54 | "laravel": { 55 | "dont-discover": [] 56 | } 57 | }, 58 | "config": { 59 | "optimize-autoloader": true, 60 | "preferred-install": "dist", 61 | "sort-packages": true 62 | }, 63 | "minimum-stability": "dev", 64 | "prefer-stable": true 65 | } 66 | -------------------------------------------------------------------------------- /config/auth.php: -------------------------------------------------------------------------------- 1 | [ 17 | 'guard' => 'web', 18 | 'passwords' => 'users', 19 | ], 20 | 21 | /* 22 | |-------------------------------------------------------------------------- 23 | | Authentication Guards 24 | |-------------------------------------------------------------------------- 25 | | 26 | | Next, you may define every authentication guard for your application. 27 | | Of course, a great default configuration has been defined for you 28 | | here which uses session storage and the Eloquent user provider. 29 | | 30 | | All authentication drivers have a user provider. This defines how the 31 | | users are actually retrieved out of your database or other storage 32 | | mechanisms used by this application to persist your user's data. 33 | | 34 | | Supported: "session" 35 | | 36 | */ 37 | 38 | 'guards' => [ 39 | 'web' => [ 40 | 'driver' => 'session', 41 | 'provider' => 'users', 42 | ], 43 | ], 44 | 45 | /* 46 | |-------------------------------------------------------------------------- 47 | | User Providers 48 | |-------------------------------------------------------------------------- 49 | | 50 | | All authentication drivers have a user provider. This defines how the 51 | | users are actually retrieved out of your database or other storage 52 | | mechanisms used by this application to persist your user's data. 53 | | 54 | | If you have multiple user tables or models you may configure multiple 55 | | sources which represent each model / table. These sources may then 56 | | be assigned to any extra authentication guards you have defined. 57 | | 58 | | Supported: "database", "eloquent" 59 | | 60 | */ 61 | 62 | 'providers' => [ 63 | 'users' => [ 64 | 'driver' => 'eloquent', 65 | 'model' => App\Models\User::class, 66 | ], 67 | 68 | // 'users' => [ 69 | // 'driver' => 'database', 70 | // 'table' => 'users', 71 | // ], 72 | ], 73 | 74 | /* 75 | |-------------------------------------------------------------------------- 76 | | Resetting Passwords 77 | |-------------------------------------------------------------------------- 78 | | 79 | | You may specify multiple password reset configurations if you have more 80 | | than one user table or model in the application and you want to have 81 | | separate password reset settings based on the specific user types. 82 | | 83 | | The expire time is the number of minutes that each reset token will be 84 | | considered valid. This security feature keeps tokens short-lived so 85 | | they have less time to be guessed. You may change this as needed. 86 | | 87 | */ 88 | 89 | 'passwords' => [ 90 | 'users' => [ 91 | 'provider' => 'users', 92 | 'table' => 'password_resets', 93 | 'expire' => 60, 94 | 'throttle' => 60, 95 | ], 96 | ], 97 | 98 | /* 99 | |-------------------------------------------------------------------------- 100 | | Password Confirmation Timeout 101 | |-------------------------------------------------------------------------- 102 | | 103 | | Here you may define the amount of seconds before a password confirmation 104 | | times out and the user is prompted to re-enter their password via the 105 | | confirmation screen. By default, the timeout lasts for three hours. 106 | | 107 | */ 108 | 109 | 'password_timeout' => 10800, 110 | 111 | ]; 112 | -------------------------------------------------------------------------------- /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 | 'client_options' => [ 43 | // Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html 44 | ], 45 | ], 46 | 47 | 'ably' => [ 48 | 'driver' => 'ably', 49 | 'key' => env('ABLY_KEY'), 50 | ], 51 | 52 | 'redis' => [ 53 | 'driver' => 'redis', 54 | 'connection' => 'default', 55 | ], 56 | 57 | 'log' => [ 58 | 'driver' => 'log', 59 | ], 60 | 61 | 'null' => [ 62 | 'driver' => 'null', 63 | ], 64 | 65 | ], 66 | 67 | ]; 68 | -------------------------------------------------------------------------------- /config/cache.php: -------------------------------------------------------------------------------- 1 | env('CACHE_DRIVER', 'file'), 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Cache Stores 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here you may define all of the cache "stores" for your application as 26 | | well as their drivers. You may even define multiple stores for the 27 | | same cache driver to group types of items stored in your caches. 28 | | 29 | | Supported drivers: "apc", "array", "database", "file", 30 | | "memcached", "redis", "dynamodb", "octane", "null" 31 | | 32 | */ 33 | 34 | 'stores' => [ 35 | 36 | 'apc' => [ 37 | 'driver' => 'apc', 38 | ], 39 | 40 | 'array' => [ 41 | 'driver' => 'array', 42 | 'serialize' => false, 43 | ], 44 | 45 | 'database' => [ 46 | 'driver' => 'database', 47 | 'table' => 'cache', 48 | 'connection' => null, 49 | 'lock_connection' => null, 50 | ], 51 | 52 | 'file' => [ 53 | 'driver' => 'file', 54 | 'path' => storage_path('framework/cache/data'), 55 | ], 56 | 57 | 'memcached' => [ 58 | 'driver' => 'memcached', 59 | 'persistent_id' => env('MEMCACHED_PERSISTENT_ID'), 60 | 'sasl' => [ 61 | env('MEMCACHED_USERNAME'), 62 | env('MEMCACHED_PASSWORD'), 63 | ], 64 | 'options' => [ 65 | // Memcached::OPT_CONNECT_TIMEOUT => 2000, 66 | ], 67 | 'servers' => [ 68 | [ 69 | 'host' => env('MEMCACHED_HOST', '127.0.0.1'), 70 | 'port' => env('MEMCACHED_PORT', 11211), 71 | 'weight' => 100, 72 | ], 73 | ], 74 | ], 75 | 76 | 'redis' => [ 77 | 'driver' => 'redis', 78 | 'connection' => 'cache', 79 | 'lock_connection' => 'default', 80 | ], 81 | 82 | 'dynamodb' => [ 83 | 'driver' => 'dynamodb', 84 | 'key' => env('AWS_ACCESS_KEY_ID'), 85 | 'secret' => env('AWS_SECRET_ACCESS_KEY'), 86 | 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), 87 | 'table' => env('DYNAMODB_CACHE_TABLE', 'cache'), 88 | 'endpoint' => env('DYNAMODB_ENDPOINT'), 89 | ], 90 | 91 | 'octane' => [ 92 | 'driver' => 'octane', 93 | ], 94 | 95 | ], 96 | 97 | /* 98 | |-------------------------------------------------------------------------- 99 | | Cache Key Prefix 100 | |-------------------------------------------------------------------------- 101 | | 102 | | When utilizing the APC, database, memcached, Redis, or DynamoDB cache 103 | | stores there might be other applications using the same cache. For 104 | | that reason, you may prefix every cache key to avoid collisions. 105 | | 106 | */ 107 | 108 | 'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_cache_'), 109 | 110 | ]; 111 | -------------------------------------------------------------------------------- /config/cors.php: -------------------------------------------------------------------------------- 1 | ['api/*', 'sanctum/csrf-cookie'], 19 | 20 | 'allowed_methods' => ['*'], 21 | 22 | 'allowed_origins' => ['*'], 23 | 24 | 'allowed_origins_patterns' => [], 25 | 26 | 'allowed_headers' => ['*'], 27 | 28 | 'exposed_headers' => [], 29 | 30 | 'max_age' => 0, 31 | 32 | 'supports_credentials' => false, 33 | 34 | ]; 35 | -------------------------------------------------------------------------------- /config/filesystems.php: -------------------------------------------------------------------------------- 1 | env('FILESYSTEM_DISK', 'local'), 17 | 18 | /* 19 | |-------------------------------------------------------------------------- 20 | | Filesystem Disks 21 | |-------------------------------------------------------------------------- 22 | | 23 | | Here you may configure as many filesystem "disks" as you wish, and you 24 | | may even configure multiple disks of the same driver. Defaults have 25 | | been set up for each driver as an example of the required values. 26 | | 27 | | Supported Drivers: "local", "ftp", "sftp", "s3" 28 | | 29 | */ 30 | 31 | 'disks' => [ 32 | 33 | 'local' => [ 34 | 'driver' => 'local', 35 | 'root' => storage_path('app'), 36 | 'throw' => false, 37 | ], 38 | 39 | 'public' => [ 40 | 'driver' => 'local', 41 | 'root' => storage_path('app/public'), 42 | 'url' => env('APP_URL').'/storage', 43 | 'visibility' => 'public', 44 | 'throw' => false, 45 | ], 46 | 47 | 's3' => [ 48 | 'driver' => 's3', 49 | 'key' => env('AWS_ACCESS_KEY_ID'), 50 | 'secret' => env('AWS_SECRET_ACCESS_KEY'), 51 | 'region' => env('AWS_DEFAULT_REGION'), 52 | 'bucket' => env('AWS_BUCKET'), 53 | 'url' => env('AWS_URL'), 54 | 'endpoint' => env('AWS_ENDPOINT'), 55 | 'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false), 56 | 'throw' => false, 57 | ], 58 | 59 | ], 60 | 61 | /* 62 | |-------------------------------------------------------------------------- 63 | | Symbolic Links 64 | |-------------------------------------------------------------------------- 65 | | 66 | | Here you may configure the symbolic links that will be created when the 67 | | `storage:link` Artisan command is executed. The array keys should be 68 | | the locations of the links and the values should be their targets. 69 | | 70 | */ 71 | 72 | 'links' => [ 73 | public_path('storage') => storage_path('app/public'), 74 | ], 75 | 76 | ]; 77 | -------------------------------------------------------------------------------- /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' => 65536, 48 | 'threads' => 1, 49 | 'time' => 4, 50 | ], 51 | 52 | ]; 53 | -------------------------------------------------------------------------------- /config/logging.php: -------------------------------------------------------------------------------- 1 | env('LOG_CHANNEL', 'stack'), 21 | 22 | /* 23 | |-------------------------------------------------------------------------- 24 | | Deprecations Log Channel 25 | |-------------------------------------------------------------------------- 26 | | 27 | | This option controls the log channel that should be used to log warnings 28 | | regarding deprecated PHP and library features. This allows you to get 29 | | your application ready for upcoming major versions of dependencies. 30 | | 31 | */ 32 | 33 | 'deprecations' => [ 34 | 'channel' => env('LOG_DEPRECATIONS_CHANNEL', 'null'), 35 | 'trace' => false, 36 | ], 37 | 38 | /* 39 | |-------------------------------------------------------------------------- 40 | | Log Channels 41 | |-------------------------------------------------------------------------- 42 | | 43 | | Here you may configure the log channels for your application. Out of 44 | | the box, Laravel uses the Monolog PHP logging library. This gives 45 | | you a variety of powerful log handlers / formatters to utilize. 46 | | 47 | | Available Drivers: "single", "daily", "slack", "syslog", 48 | | "errorlog", "monolog", 49 | | "custom", "stack" 50 | | 51 | */ 52 | 53 | 'channels' => [ 54 | 'stack' => [ 55 | 'driver' => 'stack', 56 | 'channels' => ['single'], 57 | 'ignore_exceptions' => false, 58 | ], 59 | 60 | 'single' => [ 61 | 'driver' => 'single', 62 | 'path' => storage_path('logs/laravel.log'), 63 | 'level' => env('LOG_LEVEL', 'debug'), 64 | ], 65 | 66 | 'daily' => [ 67 | 'driver' => 'daily', 68 | 'path' => storage_path('logs/laravel.log'), 69 | 'level' => env('LOG_LEVEL', 'debug'), 70 | 'days' => 14, 71 | ], 72 | 73 | 'slack' => [ 74 | 'driver' => 'slack', 75 | 'url' => env('LOG_SLACK_WEBHOOK_URL'), 76 | 'username' => 'Laravel Log', 77 | 'emoji' => ':boom:', 78 | 'level' => env('LOG_LEVEL', 'critical'), 79 | ], 80 | 81 | 'papertrail' => [ 82 | 'driver' => 'monolog', 83 | 'level' => env('LOG_LEVEL', 'debug'), 84 | 'handler' => env('LOG_PAPERTRAIL_HANDLER', SyslogUdpHandler::class), 85 | 'handler_with' => [ 86 | 'host' => env('PAPERTRAIL_URL'), 87 | 'port' => env('PAPERTRAIL_PORT'), 88 | 'connectionString' => 'tls://'.env('PAPERTRAIL_URL').':'.env('PAPERTRAIL_PORT'), 89 | ], 90 | ], 91 | 92 | 'stderr' => [ 93 | 'driver' => 'monolog', 94 | 'level' => env('LOG_LEVEL', 'debug'), 95 | 'handler' => StreamHandler::class, 96 | 'formatter' => env('LOG_STDERR_FORMATTER'), 97 | 'with' => [ 98 | 'stream' => 'php://stderr', 99 | ], 100 | ], 101 | 102 | 'syslog' => [ 103 | 'driver' => 'syslog', 104 | 'level' => env('LOG_LEVEL', 'debug'), 105 | ], 106 | 107 | 'errorlog' => [ 108 | 'driver' => 'errorlog', 109 | 'level' => env('LOG_LEVEL', 'debug'), 110 | ], 111 | 112 | 'null' => [ 113 | 'driver' => 'monolog', 114 | 'handler' => NullHandler::class, 115 | ], 116 | 117 | 'emergency' => [ 118 | 'path' => storage_path('logs/laravel.log'), 119 | ], 120 | ], 121 | 122 | ]; 123 | -------------------------------------------------------------------------------- /config/mail.php: -------------------------------------------------------------------------------- 1 | env('MAIL_MAILER', 'smtp'), 17 | 18 | /* 19 | |-------------------------------------------------------------------------- 20 | | Mailer Configurations 21 | |-------------------------------------------------------------------------- 22 | | 23 | | Here you may configure all of the mailers used by your application plus 24 | | their respective settings. Several examples have been configured for 25 | | you and you are free to add your own as your application requires. 26 | | 27 | | Laravel supports a variety of mail "transport" drivers to be used while 28 | | sending an e-mail. You will specify which one you are using for your 29 | | mailers below. You are free to add additional mailers as required. 30 | | 31 | | Supported: "smtp", "sendmail", "mailgun", "ses", 32 | | "postmark", "log", "array", "failover" 33 | | 34 | */ 35 | 36 | 'mailers' => [ 37 | 'smtp' => [ 38 | 'transport' => 'smtp', 39 | 'host' => env('MAIL_HOST', 'smtp.mailgun.org'), 40 | 'port' => env('MAIL_PORT', 587), 41 | 'encryption' => env('MAIL_ENCRYPTION', 'tls'), 42 | 'username' => env('MAIL_USERNAME'), 43 | 'password' => env('MAIL_PASSWORD'), 44 | 'timeout' => null, 45 | ], 46 | 47 | 'ses' => [ 48 | 'transport' => 'ses', 49 | ], 50 | 51 | 'mailgun' => [ 52 | 'transport' => 'mailgun', 53 | ], 54 | 55 | 'postmark' => [ 56 | 'transport' => 'postmark', 57 | ], 58 | 59 | 'sendmail' => [ 60 | 'transport' => 'sendmail', 61 | 'path' => env('MAIL_SENDMAIL_PATH', '/usr/sbin/sendmail -bs -i'), 62 | ], 63 | 64 | 'log' => [ 65 | 'transport' => 'log', 66 | 'channel' => env('MAIL_LOG_CHANNEL'), 67 | ], 68 | 69 | 'array' => [ 70 | 'transport' => 'array', 71 | ], 72 | 73 | 'failover' => [ 74 | 'transport' => 'failover', 75 | 'mailers' => [ 76 | 'smtp', 77 | 'log', 78 | ], 79 | ], 80 | ], 81 | 82 | /* 83 | |-------------------------------------------------------------------------- 84 | | Global "From" Address 85 | |-------------------------------------------------------------------------- 86 | | 87 | | You may wish for all e-mails sent by your application to be sent from 88 | | the same address. Here, you may specify a name and address that is 89 | | used globally for all e-mails that are sent by your application. 90 | | 91 | */ 92 | 93 | 'from' => [ 94 | 'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'), 95 | 'name' => env('MAIL_FROM_NAME', 'Example'), 96 | ], 97 | 98 | /* 99 | |-------------------------------------------------------------------------- 100 | | Markdown Mail Settings 101 | |-------------------------------------------------------------------------- 102 | | 103 | | If you are using Markdown based email rendering, you may configure your 104 | | theme and component paths here, allowing you to customize the design 105 | | of the emails. Or, you may simply stick with the Laravel defaults! 106 | | 107 | */ 108 | 109 | 'markdown' => [ 110 | 'theme' => 'default', 111 | 112 | 'paths' => [ 113 | resource_path('views/vendor/mail'), 114 | ], 115 | ], 116 | 117 | ]; 118 | -------------------------------------------------------------------------------- /config/queue.php: -------------------------------------------------------------------------------- 1 | env('QUEUE_CONNECTION', 'sync'), 17 | 18 | /* 19 | |-------------------------------------------------------------------------- 20 | | Queue Connections 21 | |-------------------------------------------------------------------------- 22 | | 23 | | Here you may configure the connection information for each server that 24 | | is used by your application. A default configuration has been added 25 | | for each back-end shipped with Laravel. You are free to add more. 26 | | 27 | | Drivers: "sync", "database", "beanstalkd", "sqs", "redis", "null" 28 | | 29 | */ 30 | 31 | 'connections' => [ 32 | 33 | 'sync' => [ 34 | 'driver' => 'sync', 35 | ], 36 | 37 | 'database' => [ 38 | 'driver' => 'database', 39 | 'table' => 'jobs', 40 | 'queue' => 'default', 41 | 'retry_after' => 90, 42 | 'after_commit' => false, 43 | ], 44 | 45 | 'beanstalkd' => [ 46 | 'driver' => 'beanstalkd', 47 | 'host' => 'localhost', 48 | 'queue' => 'default', 49 | 'retry_after' => 90, 50 | 'block_for' => 0, 51 | 'after_commit' => false, 52 | ], 53 | 54 | 'sqs' => [ 55 | 'driver' => 'sqs', 56 | 'key' => env('AWS_ACCESS_KEY_ID'), 57 | 'secret' => env('AWS_SECRET_ACCESS_KEY'), 58 | 'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'), 59 | 'queue' => env('SQS_QUEUE', 'default'), 60 | 'suffix' => env('SQS_SUFFIX'), 61 | 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), 62 | 'after_commit' => false, 63 | ], 64 | 65 | 'redis' => [ 66 | 'driver' => 'redis', 67 | 'connection' => 'default', 68 | 'queue' => env('REDIS_QUEUE', 'default'), 69 | 'retry_after' => 90, 70 | 'block_for' => null, 71 | 'after_commit' => false, 72 | ], 73 | 74 | ], 75 | 76 | /* 77 | |-------------------------------------------------------------------------- 78 | | Failed Queue Jobs 79 | |-------------------------------------------------------------------------- 80 | | 81 | | These options configure the behavior of failed queue job logging so you 82 | | can control which database and table are used to store the jobs that 83 | | have failed. You may change them to any database / table you wish. 84 | | 85 | */ 86 | 87 | 'failed' => [ 88 | 'driver' => env('QUEUE_FAILED_DRIVER', 'database-uuids'), 89 | 'database' => env('DB_CONNECTION', 'mysql'), 90 | 'table' => 'failed_jobs', 91 | ], 92 | 93 | ]; 94 | -------------------------------------------------------------------------------- /config/sanctum.php: -------------------------------------------------------------------------------- 1 | explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf( 19 | '%s%s', 20 | 'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1', 21 | Sanctum::currentApplicationUrlWithPort() 22 | ))), 23 | 24 | /* 25 | |-------------------------------------------------------------------------- 26 | | Sanctum Guards 27 | |-------------------------------------------------------------------------- 28 | | 29 | | This array contains the authentication guards that will be checked when 30 | | Sanctum is trying to authenticate a request. If none of these guards 31 | | are able to authenticate the request, Sanctum will use the bearer 32 | | token that's present on an incoming request for authentication. 33 | | 34 | */ 35 | 36 | 'guard' => ['web'], 37 | 38 | /* 39 | |-------------------------------------------------------------------------- 40 | | Expiration Minutes 41 | |-------------------------------------------------------------------------- 42 | | 43 | | This value controls the number of minutes until an issued token will be 44 | | considered expired. If this value is null, personal access tokens do 45 | | not expire. This won't tweak the lifetime of first-party sessions. 46 | | 47 | */ 48 | 49 | 'expiration' => null, 50 | 51 | /* 52 | |-------------------------------------------------------------------------- 53 | | Sanctum Middleware 54 | |-------------------------------------------------------------------------- 55 | | 56 | | When authenticating your first-party SPA with Sanctum you may need to 57 | | customize some of the middleware Sanctum uses while processing the 58 | | request. You may change the middleware listed below as required. 59 | | 60 | */ 61 | 62 | 'middleware' => [ 63 | 'verify_csrf_token' => App\Http\Middleware\VerifyCsrfToken::class, 64 | 'encrypt_cookies' => App\Http\Middleware\EncryptCookies::class, 65 | ], 66 | 67 | ]; 68 | -------------------------------------------------------------------------------- /config/services.php: -------------------------------------------------------------------------------- 1 | [ 18 | 'domain' => env('MAILGUN_DOMAIN'), 19 | 'secret' => env('MAILGUN_SECRET'), 20 | 'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'), 21 | 'scheme' => 'https', 22 | ], 23 | 24 | 'postmark' => [ 25 | 'token' => env('POSTMARK_TOKEN'), 26 | ], 27 | 28 | 'ses' => [ 29 | 'key' => env('AWS_ACCESS_KEY_ID'), 30 | 'secret' => env('AWS_SECRET_ACCESS_KEY'), 31 | 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), 32 | ], 33 | 34 | ]; 35 | -------------------------------------------------------------------------------- /config/view.php: -------------------------------------------------------------------------------- 1 | [ 17 | resource_path('views'), 18 | ], 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Compiled View Path 23 | |-------------------------------------------------------------------------- 24 | | 25 | | This option determines where all the compiled Blade templates will be 26 | | stored for your application. Typically, this is within the storage 27 | | directory. However, as usual, you are free to change this value. 28 | | 29 | */ 30 | 31 | 'compiled' => env( 32 | 'VIEW_COMPILED_PATH', 33 | realpath(storage_path('framework/views')) 34 | ), 35 | 36 | ]; 37 | -------------------------------------------------------------------------------- /database/.gitignore: -------------------------------------------------------------------------------- 1 | *.sqlite* 2 | -------------------------------------------------------------------------------- /database/factories/UserFactory.php: -------------------------------------------------------------------------------- 1 | 10 | */ 11 | class UserFactory extends Factory 12 | { 13 | /** 14 | * Define the model's default state. 15 | * 16 | * @return array 17 | */ 18 | public function definition() 19 | { 20 | return [ 21 | 'name' => $this->faker->name(), 22 | 'email' => $this->faker->unique()->safeEmail(), 23 | 'email_verified_at' => now(), 24 | 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password 25 | 'remember_token' => Str::random(10), 26 | ]; 27 | } 28 | 29 | /** 30 | * Indicate that the model's email address should be unverified. 31 | * 32 | * @return static 33 | */ 34 | public function unverified() 35 | { 36 | return $this->state(function (array $attributes) { 37 | return [ 38 | 'email_verified_at' => null, 39 | ]; 40 | }); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /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->rememberToken(); 23 | $table->timestamps(); 24 | }); 25 | } 26 | 27 | /** 28 | * Reverse the migrations. 29 | * 30 | * @return void 31 | */ 32 | public function down() 33 | { 34 | Schema::dropIfExists('users'); 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /database/migrations/2014_10_12_100000_create_password_resets_table.php: -------------------------------------------------------------------------------- 1 | string('email')->index(); 18 | $table->string('token'); 19 | $table->timestamp('created_at')->nullable(); 20 | }); 21 | } 22 | 23 | /** 24 | * Reverse the migrations. 25 | * 26 | * @return void 27 | */ 28 | public function down() 29 | { 30 | Schema::dropIfExists('password_resets'); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /database/migrations/2019_08_19_000000_create_failed_jobs_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->string('uuid')->unique(); 19 | $table->text('connection'); 20 | $table->text('queue'); 21 | $table->longText('payload'); 22 | $table->longText('exception'); 23 | $table->timestamp('failed_at')->useCurrent(); 24 | }); 25 | } 26 | 27 | /** 28 | * Reverse the migrations. 29 | * 30 | * @return void 31 | */ 32 | public function down() 33 | { 34 | Schema::dropIfExists('failed_jobs'); 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->morphs('tokenable'); 19 | $table->string('name'); 20 | $table->string('token', 64)->unique(); 21 | $table->text('abilities')->nullable(); 22 | $table->timestamp('last_used_at')->nullable(); 23 | $table->timestamps(); 24 | }); 25 | } 26 | 27 | /** 28 | * Reverse the migrations. 29 | * 30 | * @return void 31 | */ 32 | public function down() 33 | { 34 | Schema::dropIfExists('personal_access_tokens'); 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /database/migrations/2022_05_09_062500_create_spaces_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->string('name'); 19 | $table->string('slug'); 20 | $table->string('image')->nullable(); 21 | $table->string('location'); 22 | $table->longText('content'); 23 | $table->timestamps(); 24 | }); 25 | } 26 | 27 | /** 28 | * Reverse the migrations. 29 | * 30 | * @return void 31 | */ 32 | public function down() 33 | { 34 | Schema::dropIfExists('spaces'); 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /database/migrations/2022_05_12_052741_create_centre_points_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->string('location'); 19 | $table->timestamps(); 20 | }); 21 | } 22 | 23 | /** 24 | * Reverse the migrations. 25 | * 26 | * @return void 27 | */ 28 | public function down() 29 | { 30 | Schema::dropIfExists('centre_points'); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /database/seeders/DatabaseSeeder.php: -------------------------------------------------------------------------------- 1 | create(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lang/en/auth.php: -------------------------------------------------------------------------------- 1 | 'These credentials do not match our records.', 17 | 'password' => 'The provided password is incorrect.', 18 | 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.', 19 | 20 | ]; 21 | -------------------------------------------------------------------------------- /lang/en/pagination.php: -------------------------------------------------------------------------------- 1 | '« Previous', 17 | 'next' => 'Next »', 18 | 19 | ]; 20 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "dev": "npm run development", 5 | "development": "mix", 6 | "watch": "mix watch", 7 | "watch-poll": "mix watch -- --watch-options-poll=1000", 8 | "hot": "mix watch --hot", 9 | "prod": "npm run production", 10 | "production": "mix --production" 11 | }, 12 | "devDependencies": { 13 | "@popperjs/core": "^2.10.2", 14 | "axios": "^0.25", 15 | "bootstrap": "^5.1.3", 16 | "laravel-mix": "^6.0.6", 17 | "lodash": "^4.17.19", 18 | "postcss": "^8.1.14", 19 | "resolve-url-loader": "^5.0.0", 20 | "sass": "^1.32.11", 21 | "sass-loader": "^11.0.1" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | ./tests/Unit 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 | 32 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Tristan Edwards & Limon Monte 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/SweetAlert.js: -------------------------------------------------------------------------------- 1 | import { error } from './utils/utils.js' 2 | import { DismissReason } from './utils/DismissReason.js' 3 | import * as staticMethods from './staticMethods.js' 4 | import * as instanceMethods from './instanceMethods.js' 5 | import privateProps from './privateProps.js' 6 | 7 | let currentInstance 8 | 9 | class SweetAlert { 10 | constructor (...args) { 11 | // Prevent run in Node env 12 | if (typeof window === 'undefined') { 13 | return 14 | } 15 | 16 | // Check for the existence of Promise 17 | if (typeof Promise === 'undefined') { 18 | error('This package requires a Promise library, please include a shim to enable it in this browser (See: https://github.com/sweetalert2/sweetalert2/wiki/Migration-from-SweetAlert-to-SweetAlert2#1-ie-support)') 19 | } 20 | 21 | currentInstance = this 22 | 23 | const outerParams = Object.freeze(this.constructor.argsToParams(args)) 24 | 25 | Object.defineProperties(this, { 26 | params: { 27 | value: outerParams, 28 | writable: false, 29 | enumerable: true, 30 | configurable: true 31 | } 32 | }) 33 | 34 | const promise = this._main(this.params) 35 | privateProps.promise.set(this, promise) 36 | } 37 | 38 | // `catch` cannot be the name of a module export, so we define our thenable methods here instead 39 | then (onFulfilled) { 40 | const promise = privateProps.promise.get(this) 41 | return promise.then(onFulfilled) 42 | } 43 | 44 | finally (onFinally) { 45 | const promise = privateProps.promise.get(this) 46 | return promise.finally(onFinally) 47 | } 48 | } 49 | 50 | // Assign instance methods from src/instanceMethods/*.js to prototype 51 | Object.assign(SweetAlert.prototype, instanceMethods) 52 | 53 | // Assign static methods from src/staticMethods/*.js to constructor 54 | Object.assign(SweetAlert, staticMethods) 55 | 56 | // Proxy to instance methods to constructor, for now, for backwards compatibility 57 | Object.keys(instanceMethods).forEach(key => { 58 | SweetAlert[key] = function (...args) { 59 | if (currentInstance) { 60 | return currentInstance[key](...args) 61 | } 62 | } 63 | }) 64 | 65 | SweetAlert.DismissReason = DismissReason 66 | 67 | SweetAlert.version = '10.3.6' 68 | 69 | export default SweetAlert 70 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/constants.js: -------------------------------------------------------------------------------- 1 | export const RESTORE_FOCUS_TIMEOUT = 100 2 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/globalState.js: -------------------------------------------------------------------------------- 1 | import { RESTORE_FOCUS_TIMEOUT } from './constants.js' 2 | 3 | const globalState = {} 4 | 5 | export default globalState 6 | 7 | const focusPreviousActiveElement = () => { 8 | if (globalState.previousActiveElement && globalState.previousActiveElement.focus) { 9 | globalState.previousActiveElement.focus() 10 | globalState.previousActiveElement = null 11 | } else if (document.body) { 12 | document.body.focus() 13 | } 14 | } 15 | 16 | // Restore previous active (focused) element 17 | export const restoreActiveElement = () => { 18 | return new Promise(resolve => { 19 | const x = window.scrollX 20 | const y = window.scrollY 21 | globalState.restoreFocusTimeout = setTimeout(() => { 22 | focusPreviousActiveElement() 23 | resolve() 24 | }, RESTORE_FOCUS_TIMEOUT) // issues/900 25 | /* istanbul ignore if */ 26 | if (typeof x !== 'undefined' && typeof y !== 'undefined') { // IE doesn't have scrollX/scrollY support 27 | window.scrollTo(x, y) 28 | } 29 | }) 30 | } 31 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/instanceMethods.js: -------------------------------------------------------------------------------- 1 | export * from './instanceMethods/hideLoading.js' 2 | export * from './instanceMethods/getInput.js' 3 | export * from './instanceMethods/close.js' 4 | export * from './instanceMethods/enable-disable-elements.js' 5 | export * from './instanceMethods/show-reset-validation-error.js' 6 | export * from './instanceMethods/progress-steps.js' 7 | export * from './instanceMethods/_main.js' 8 | export * from './instanceMethods/update.js' 9 | export * from './instanceMethods/_destroy.js' 10 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/instanceMethods/_destroy.js: -------------------------------------------------------------------------------- 1 | import globalState from '../globalState.js' 2 | import privateProps from '../privateProps.js' 3 | import privateMethods from '../privateMethods.js' 4 | 5 | export function _destroy () { 6 | const domCache = privateProps.domCache.get(this) 7 | const innerParams = privateProps.innerParams.get(this) 8 | 9 | if (!innerParams) { 10 | return // This instance has already been destroyed 11 | } 12 | 13 | // Check if there is another Swal closing 14 | if (domCache.popup && globalState.swalCloseEventFinishedCallback) { 15 | globalState.swalCloseEventFinishedCallback() 16 | delete globalState.swalCloseEventFinishedCallback 17 | } 18 | 19 | // Check if there is a swal disposal defer timer 20 | if (globalState.deferDisposalTimer) { 21 | clearTimeout(globalState.deferDisposalTimer) 22 | delete globalState.deferDisposalTimer 23 | } 24 | 25 | runDidDestroy(innerParams) 26 | 27 | disposeSwal(this) 28 | } 29 | 30 | const runDidDestroy = (innerParams) => { 31 | if (typeof innerParams.didDestroy === 'function') { 32 | innerParams.didDestroy() 33 | } else if (typeof innerParams.onDestroy === 'function') { 34 | innerParams.onDestroy() // @deprecated 35 | } 36 | } 37 | 38 | const disposeSwal = (instance) => { 39 | // Unset this.params so GC will dispose it (#1569) 40 | delete instance.params 41 | // Unset globalState props so GC will dispose globalState (#1569) 42 | delete globalState.keydownHandler 43 | delete globalState.keydownTarget 44 | // Unset WeakMaps so GC will be able to dispose them (#1569) 45 | unsetWeakMaps(privateProps) 46 | unsetWeakMaps(privateMethods) 47 | } 48 | 49 | const unsetWeakMaps = (obj) => { 50 | for (const i in obj) { 51 | obj[i] = new WeakMap() 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/instanceMethods/buttons-handlers.js: -------------------------------------------------------------------------------- 1 | import { isVisible } from '../utils/dom/domUtils.js' 2 | import { getInputValue } from '../utils/dom/inputUtils.js' 3 | import { getValidationMessage } from '../utils/dom/getters.js' 4 | import { asPromise } from '../utils/utils.js' 5 | import { showLoading } from '../staticMethods/showLoading.js' 6 | import { DismissReason } from '../utils/DismissReason.js' 7 | 8 | export const handleConfirmButtonClick = (instance, innerParams) => { 9 | instance.disableButtons() 10 | if (innerParams.input) { 11 | handleConfirmWithInput(instance, innerParams) 12 | } else { 13 | confirm(instance, innerParams, true) 14 | } 15 | } 16 | 17 | export const handleDenyButtonClick = (instance) => { 18 | instance.disableButtons() 19 | // here we could add preDeny in future, if needed 20 | deny(instance) 21 | } 22 | 23 | export const handleCancelButtonClick = (instance, dismissWith) => { 24 | instance.disableButtons() 25 | dismissWith(DismissReason.cancel) 26 | } 27 | 28 | const handleConfirmWithInput = (instance, innerParams) => { 29 | const inputValue = getInputValue(instance, innerParams) 30 | 31 | if (innerParams.inputValidator) { 32 | instance.disableInput() 33 | const validationPromise = Promise.resolve().then(() => asPromise( 34 | innerParams.inputValidator(inputValue, innerParams.validationMessage)) 35 | ) 36 | validationPromise.then( 37 | (validationMessage) => { 38 | instance.enableButtons() 39 | instance.enableInput() 40 | if (validationMessage) { 41 | instance.showValidationMessage(validationMessage) 42 | } else { 43 | confirm(instance, innerParams, inputValue) 44 | } 45 | } 46 | ) 47 | } else if (!instance.getInput().checkValidity()) { 48 | instance.enableButtons() 49 | instance.showValidationMessage(innerParams.validationMessage) 50 | } else { 51 | confirm(instance, innerParams, inputValue) 52 | } 53 | } 54 | 55 | const deny = (instance) => { 56 | instance.closePopup({ isDenied: true, value: false }) 57 | } 58 | 59 | const succeedWith = (instance, value) => { 60 | instance.closePopup({ isConfirmed: true, value }) 61 | } 62 | 63 | const confirm = (instance, innerParams, value) => { 64 | if (innerParams.showLoaderOnConfirm) { 65 | showLoading() // TODO: make showLoading an *instance* method 66 | } 67 | 68 | if (innerParams.preConfirm) { 69 | instance.resetValidationMessage() 70 | const preConfirmPromise = Promise.resolve().then(() => asPromise( 71 | innerParams.preConfirm(value, innerParams.validationMessage)) 72 | ) 73 | preConfirmPromise.then( 74 | (preConfirmValue) => { 75 | if (isVisible(getValidationMessage()) || preConfirmValue === false) { 76 | instance.hideLoading() 77 | } else { 78 | succeedWith(instance, typeof preConfirmValue === 'undefined' ? value : preConfirmValue) 79 | } 80 | } 81 | ) 82 | } else { 83 | succeedWith(instance, value) 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/instanceMethods/enable-disable-elements.js: -------------------------------------------------------------------------------- 1 | import privateProps from '../privateProps.js' 2 | 3 | function setButtonsDisabled (instance, buttons, disabled) { 4 | const domCache = privateProps.domCache.get(instance) 5 | buttons.forEach(button => { 6 | domCache[button].disabled = disabled 7 | }) 8 | } 9 | 10 | function setInputDisabled (input, disabled) { 11 | if (!input) { 12 | return false 13 | } 14 | if (input.type === 'radio') { 15 | const radiosContainer = input.parentNode.parentNode 16 | const radios = radiosContainer.querySelectorAll('input') 17 | for (let i = 0; i < radios.length; i++) { 18 | radios[i].disabled = disabled 19 | } 20 | } else { 21 | input.disabled = disabled 22 | } 23 | } 24 | 25 | export function enableButtons () { 26 | setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], false) 27 | } 28 | 29 | export function disableButtons () { 30 | setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], true) 31 | } 32 | 33 | export function enableInput () { 34 | return setInputDisabled(this.getInput(), false) 35 | } 36 | 37 | export function disableInput () { 38 | return setInputDisabled(this.getInput(), true) 39 | } 40 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/instanceMethods/getInput.js: -------------------------------------------------------------------------------- 1 | import * as dom from '../utils/dom/index.js' 2 | import privateProps from '../privateProps.js' 3 | 4 | // Get input element by specified type or, if type isn't specified, by params.input 5 | export function getInput (instance) { 6 | const innerParams = privateProps.innerParams.get(instance || this) 7 | const domCache = privateProps.domCache.get(instance || this) 8 | if (!domCache) { 9 | return null 10 | } 11 | return dom.getInput(domCache.content, innerParams.input) 12 | } 13 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/instanceMethods/hideLoading.js: -------------------------------------------------------------------------------- 1 | import * as dom from '../utils/dom/index.js' 2 | import { swalClasses } from '../utils/classes.js' 3 | import privateProps from '../privateProps.js' 4 | 5 | /** 6 | * Enables buttons and hide loader. 7 | */ 8 | function hideLoading () { 9 | // do nothing if popup is closed 10 | const innerParams = privateProps.innerParams.get(this) 11 | if (!innerParams) { 12 | return 13 | } 14 | const domCache = privateProps.domCache.get(this) 15 | dom.hide(domCache.loader) 16 | if (innerParams.showConfirmButton) { 17 | dom.show(domCache.confirmButton) 18 | } else if (!innerParams.showConfirmButton && !innerParams.showCancelButton) { 19 | dom.hide(domCache.actions) 20 | } 21 | dom.removeClass([domCache.popup, domCache.actions], swalClasses.loading) 22 | domCache.popup.removeAttribute('aria-busy') 23 | domCache.popup.removeAttribute('data-loading') 24 | domCache.confirmButton.disabled = false 25 | domCache.denyButton.disabled = false 26 | domCache.cancelButton.disabled = false 27 | } 28 | 29 | export { 30 | hideLoading, 31 | hideLoading as disableLoading 32 | } 33 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/instanceMethods/popup-click-handler.js: -------------------------------------------------------------------------------- 1 | import { callIfFunction } from '../utils/utils.js' 2 | import { DismissReason } from '../utils/DismissReason.js' 3 | import privateProps from '../privateProps.js' 4 | 5 | export const handlePopupClick = (instance, domCache, dismissWith) => { 6 | const innerParams = privateProps.innerParams.get(instance) 7 | if (innerParams.toast) { 8 | handleToastClick(instance, domCache, dismissWith) 9 | } else { 10 | // Ignore click events that had mousedown on the popup but mouseup on the container 11 | // This can happen when the user drags a slider 12 | handleModalMousedown(domCache) 13 | 14 | // Ignore click events that had mousedown on the container but mouseup on the popup 15 | handleContainerMousedown(domCache) 16 | 17 | handleModalClick(instance, domCache, dismissWith) 18 | } 19 | } 20 | 21 | const handleToastClick = (instance, domCache, dismissWith) => { 22 | // Closing toast by internal click 23 | domCache.popup.onclick = () => { 24 | const innerParams = privateProps.innerParams.get(instance) 25 | if ( 26 | innerParams.showConfirmButton || 27 | innerParams.showDenyButton || 28 | innerParams.showCancelButton || 29 | innerParams.showCloseButton || 30 | innerParams.input 31 | ) { 32 | return 33 | } 34 | dismissWith(DismissReason.close) 35 | } 36 | } 37 | 38 | let ignoreOutsideClick = false 39 | 40 | const handleModalMousedown = (domCache) => { 41 | domCache.popup.onmousedown = () => { 42 | domCache.container.onmouseup = function (e) { 43 | domCache.container.onmouseup = undefined 44 | // We only check if the mouseup target is the container because usually it doesn't 45 | // have any other direct children aside of the popup 46 | if (e.target === domCache.container) { 47 | ignoreOutsideClick = true 48 | } 49 | } 50 | } 51 | } 52 | 53 | const handleContainerMousedown = (domCache) => { 54 | domCache.container.onmousedown = () => { 55 | domCache.popup.onmouseup = function (e) { 56 | domCache.popup.onmouseup = undefined 57 | // We also need to check if the mouseup target is a child of the popup 58 | if (e.target === domCache.popup || domCache.popup.contains(e.target)) { 59 | ignoreOutsideClick = true 60 | } 61 | } 62 | } 63 | } 64 | 65 | const handleModalClick = (instance, domCache, dismissWith) => { 66 | domCache.container.onclick = (e) => { 67 | const innerParams = privateProps.innerParams.get(instance) 68 | if (ignoreOutsideClick) { 69 | ignoreOutsideClick = false 70 | return 71 | } 72 | if (e.target === domCache.container && callIfFunction(innerParams.allowOutsideClick)) { 73 | dismissWith(DismissReason.backdrop) 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/instanceMethods/progress-steps.js: -------------------------------------------------------------------------------- 1 | import privateProps from '../privateProps.js' 2 | 3 | export function getProgressSteps () { 4 | const domCache = privateProps.domCache.get(this) 5 | return domCache.progressSteps 6 | } 7 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/instanceMethods/show-reset-validation-error.js: -------------------------------------------------------------------------------- 1 | import * as dom from '../utils/dom/index.js' 2 | import { swalClasses } from '../utils/classes.js' 3 | import privateProps from '../privateProps.js' 4 | 5 | // Show block with validation message 6 | export function showValidationMessage (error) { 7 | const domCache = privateProps.domCache.get(this) 8 | dom.setInnerHtml(domCache.validationMessage, error) 9 | const popupComputedStyle = window.getComputedStyle(domCache.popup) 10 | domCache.validationMessage.style.marginLeft = `-${popupComputedStyle.getPropertyValue('padding-left')}` 11 | domCache.validationMessage.style.marginRight = `-${popupComputedStyle.getPropertyValue('padding-right')}` 12 | dom.show(domCache.validationMessage) 13 | 14 | const input = this.getInput() 15 | if (input) { 16 | input.setAttribute('aria-invalid', true) 17 | input.setAttribute('aria-describedBy', swalClasses['validation-message']) 18 | dom.focusInput(input) 19 | dom.addClass(input, swalClasses.inputerror) 20 | } 21 | } 22 | 23 | // Hide block with validation message 24 | export function resetValidationMessage () { 25 | const domCache = privateProps.domCache.get(this) 26 | if (domCache.validationMessage) { 27 | dom.hide(domCache.validationMessage) 28 | } 29 | 30 | const input = this.getInput() 31 | if (input) { 32 | input.removeAttribute('aria-invalid') 33 | input.removeAttribute('aria-describedBy') 34 | dom.removeClass(input, swalClasses.inputerror) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/instanceMethods/update.js: -------------------------------------------------------------------------------- 1 | import * as dom from '../../src/utils/dom/index.js' 2 | import { warn } from '../../src/utils/utils.js' 3 | import sweetAlert from '../sweetalert2.js' 4 | import privateProps from '../privateProps.js' 5 | 6 | /** 7 | * Updates popup parameters. 8 | */ 9 | export function update (params) { 10 | const popup = dom.getPopup() 11 | const innerParams = privateProps.innerParams.get(this) 12 | 13 | if (!popup || dom.hasClass(popup, innerParams.hideClass.popup)) { 14 | return warn(`You're trying to update the closed or closing popup, that won't work. Use the update() method in preConfirm parameter or show a new popup.`) 15 | } 16 | 17 | const validUpdatableParams = {} 18 | 19 | // assign valid params from `params` to `defaults` 20 | Object.keys(params).forEach(param => { 21 | if (sweetAlert.isUpdatableParameter(param)) { 22 | validUpdatableParams[param] = params[param] 23 | } else { 24 | warn(`Invalid parameter to update: "${param}". Updatable params are listed here: https://github.com/sweetalert2/sweetalert2/blob/master/src/utils/params.js\n\nIf you think this parameter should be updatable, request it here: https://github.com/sweetalert2/sweetalert2/issues/new?template=02_feature_request.md`) 25 | } 26 | }) 27 | 28 | const updatedParams = Object.assign({}, innerParams, validUpdatableParams) 29 | 30 | dom.render(this, updatedParams) 31 | 32 | privateProps.innerParams.set(this, updatedParams) 33 | Object.defineProperties(this, { 34 | params: { 35 | value: Object.assign({}, this.params, params), 36 | writable: false, 37 | enumerable: true 38 | } 39 | }) 40 | } 41 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/privateMethods.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This module containts `WeakMap`s for each effectively-"private property" that a `Swal` has. 3 | * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')` 4 | * This is the approach that Babel will probably take to implement private methods/fields 5 | * https://github.com/tc39/proposal-private-methods 6 | * https://github.com/babel/babel/pull/7555 7 | * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module* 8 | * then we can use that language feature. 9 | */ 10 | 11 | export default { 12 | swalPromiseResolve: new WeakMap() 13 | } 14 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/privateProps.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This module containts `WeakMap`s for each effectively-"private property" that a `Swal` has. 3 | * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')` 4 | * This is the approach that Babel will probably take to implement private methods/fields 5 | * https://github.com/tc39/proposal-private-methods 6 | * https://github.com/babel/babel/pull/7555 7 | * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module* 8 | * then we can use that language feature. 9 | */ 10 | 11 | export default { 12 | promise: new WeakMap(), 13 | innerParams: new WeakMap(), 14 | domCache: new WeakMap() 15 | } 16 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/scss/_animations.scss: -------------------------------------------------------------------------------- 1 | @import 'toasts-animations'; 2 | 3 | // Appearance animation 4 | @keyframes swal2-show { 5 | 0% { 6 | transform: scale(.7); 7 | } 8 | 9 | 45% { 10 | transform: scale(1.05); 11 | } 12 | 13 | 80% { 14 | transform: scale(.95); 15 | } 16 | 17 | 100% { 18 | transform: scale(1); 19 | } 20 | } 21 | 22 | // Disppearance animation 23 | @keyframes swal2-hide { 24 | 0% { 25 | transform: scale(1); 26 | opacity: 1; 27 | } 28 | 29 | 100% { 30 | transform: scale(.5); 31 | opacity: 0; 32 | } 33 | } 34 | 35 | // Success icon animations 36 | @keyframes swal2-animate-success-line-tip { 37 | 0% { 38 | top: 1.1875em; 39 | left: .0625em; 40 | width: 0; 41 | } 42 | 43 | 54% { 44 | top: 1.0625em; 45 | left: .125em; 46 | width: 0; 47 | } 48 | 49 | 70% { 50 | top: 2.1875em; 51 | left: -.375em; 52 | width: 3.125em; 53 | } 54 | 55 | 84% { 56 | top: 3em; 57 | left: 1.3125em; 58 | width: 1.0625em; 59 | } 60 | 61 | 100% { 62 | top: 2.8125em; 63 | left: .8125em; 64 | width: 1.5625em; 65 | } 66 | } 67 | 68 | @keyframes swal2-animate-success-line-long { 69 | 0% { 70 | top: 3.375em; 71 | right: 2.875em; 72 | width: 0; 73 | } 74 | 75 | 65% { 76 | top: 3.375em; 77 | right: 2.875em; 78 | width: 0; 79 | } 80 | 81 | 84% { 82 | top: 2.1875em; 83 | right: 0; 84 | width: 3.4375em; 85 | } 86 | 87 | 100% { 88 | top: 2.375em; 89 | right: .5em; 90 | width: 2.9375em; 91 | } 92 | } 93 | 94 | @keyframes swal2-rotate-success-circular-line { 95 | 0% { 96 | transform: rotate(-45deg); 97 | } 98 | 99 | 5% { 100 | transform: rotate(-45deg); 101 | } 102 | 103 | 12% { 104 | transform: rotate(-405deg); 105 | } 106 | 107 | 100% { 108 | transform: rotate(-405deg); 109 | } 110 | } 111 | 112 | // Error icon animations 113 | @keyframes swal2-animate-error-x-mark { 114 | 0% { 115 | margin-top: 1.625em; 116 | transform: scale(.4); 117 | opacity: 0; 118 | } 119 | 120 | 50% { 121 | margin-top: 1.625em; 122 | transform: scale(.4); 123 | opacity: 0; 124 | } 125 | 126 | 80% { 127 | margin-top: -.375em; 128 | transform: scale(1.15); 129 | } 130 | 131 | 100% { 132 | margin-top: 0; 133 | transform: scale(1); 134 | opacity: 1; 135 | } 136 | } 137 | 138 | @keyframes swal2-animate-error-icon { 139 | 0% { 140 | transform: rotateX(100deg); 141 | opacity: 0; 142 | } 143 | 144 | 100% { 145 | transform: rotateX(0deg); 146 | opacity: 1; 147 | } 148 | } 149 | 150 | @keyframes swal2-rotate-loading { 151 | 0% { 152 | transform: rotate(0deg); 153 | } 154 | 155 | 100% { 156 | transform: rotate(360deg); 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/scss/_body.scss: -------------------------------------------------------------------------------- 1 | @import 'toasts-body'; 2 | 3 | @mixin sweetalert2-body() { 4 | &.swal2-shown { 5 | @include not('.swal2-no-backdrop', '.swal2-toast-shown') { 6 | overflow: hidden; // not overflow-y because of Sarari, #1253 7 | } 8 | } 9 | 10 | &.swal2-height-auto { 11 | height: auto !important; // #781 #1107 12 | } 13 | 14 | &.swal2-no-backdrop { 15 | .swal2-container { 16 | top: auto; 17 | right: auto; 18 | bottom: auto; 19 | left: auto; 20 | max-width: calc(100% - #{$swal2-container-padding} * 2); 21 | background-color: transparent !important; 22 | 23 | & > .swal2-modal { 24 | box-shadow: 0 0 10px $swal2-backdrop; 25 | } 26 | 27 | &.swal2-top { 28 | top: 0; 29 | left: 50%; 30 | transform: translateX(-50%); 31 | } 32 | 33 | &.swal2-top-start, 34 | &.swal2-top-left { 35 | top: 0; 36 | left: 0; 37 | } 38 | 39 | &.swal2-top-end, 40 | &.swal2-top-right { 41 | top: 0; 42 | right: 0; 43 | } 44 | 45 | &.swal2-center { 46 | top: 50%; 47 | left: 50%; 48 | transform: translate(-50%, -50%); 49 | } 50 | 51 | &.swal2-center-start, 52 | &.swal2-center-left { 53 | top: 50%; 54 | left: 0; 55 | transform: translateY(-50%); 56 | } 57 | 58 | &.swal2-center-end, 59 | &.swal2-center-right { 60 | top: 50%; 61 | right: 0; 62 | transform: translateY(-50%); 63 | } 64 | 65 | &.swal2-bottom { 66 | bottom: 0; 67 | left: 50%; 68 | transform: translateX(-50%); 69 | } 70 | 71 | &.swal2-bottom-start, 72 | &.swal2-bottom-left { 73 | bottom: 0; 74 | left: 0; 75 | } 76 | 77 | &.swal2-bottom-end, 78 | &.swal2-bottom-right { 79 | right: 0; 80 | bottom: 0; 81 | } 82 | } 83 | } 84 | 85 | @media print { 86 | &.swal2-shown { 87 | @include not('.swal2-no-backdrop', '.swal2-toast-shown') { 88 | overflow-y: scroll !important; 89 | 90 | > [aria-hidden='true'] { 91 | display: none; 92 | } 93 | 94 | .swal2-container { 95 | position: static !important; 96 | } 97 | } 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/scss/_mixins.scss: -------------------------------------------------------------------------------- 1 | @mixin ie { 2 | @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) { 3 | @content; 4 | } 5 | } 6 | 7 | // https://stackoverflow.com/a/30250161 8 | @mixin not($ignor-list...) { 9 | @if (length($ignor-list) == 1) { 10 | $ignor-list: nth($ignor-list, 1); 11 | } 12 | 13 | $not-output: ''; 14 | 15 | @each $not in $ignor-list { 16 | $not-output: $not-output + ':not(#{$not})'; // stylelint-disable-line scss/no-duplicate-dollar-variables 17 | } 18 | 19 | &#{$not-output} { 20 | @content; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/scss/_polyfills.scss: -------------------------------------------------------------------------------- 1 | @import '../variables'; 2 | 3 | // Microsoft Edge 4 | @supports (-ms-accelerator: true) { 5 | .swal2-range { 6 | input { 7 | width: 100% !important; 8 | } 9 | 10 | output { 11 | display: none; 12 | } 13 | } 14 | } 15 | 16 | // IE11 17 | @media all and (-ms-high-contrast: none), 18 | (-ms-high-contrast: active) { 19 | .swal2-range { 20 | input { 21 | width: 100% !important; 22 | } 23 | 24 | output { 25 | display: none; 26 | } 27 | } 28 | } 29 | 30 | // Firefox 31 | @-moz-document url-prefix() { 32 | .swal2-close { 33 | &:focus { 34 | outline: 2px solid $swal2-outline-color; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/scss/_theming.scss: -------------------------------------------------------------------------------- 1 | // base file for including when performing theming 2 | // doesn't include at-rules or root selectors (like body) which allows for more comprehensive extending 3 | 4 | @import '../variables'; 5 | @import 'mixins'; 6 | @import 'toasts'; 7 | @import 'body'; 8 | @import 'core'; 9 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/scss/_toasts-animations.scss: -------------------------------------------------------------------------------- 1 | // Animations 2 | @keyframes swal2-toast-show { 3 | 0% { 4 | transform: translateY(-.625em) rotateZ(2deg); 5 | } 6 | 7 | 33% { 8 | transform: translateY(0) rotateZ(-2deg); 9 | } 10 | 11 | 66% { 12 | transform: translateY(.3125em) rotateZ(2deg); 13 | } 14 | 15 | 100% { 16 | transform: translateY(0) rotateZ(0deg); 17 | } 18 | } 19 | 20 | @keyframes swal2-toast-hide { 21 | 100% { 22 | transform: rotateZ(1deg); 23 | opacity: 0; 24 | } 25 | } 26 | 27 | @keyframes swal2-toast-animate-success-line-tip { 28 | 0% { 29 | top: .5625em; 30 | left: .0625em; 31 | width: 0; 32 | } 33 | 34 | 54% { 35 | top: .125em; 36 | left: .125em; 37 | width: 0; 38 | } 39 | 40 | 70% { 41 | top: .625em; 42 | left: -.25em; 43 | width: 1.625em; 44 | } 45 | 46 | 84% { 47 | top: 1.0625em; 48 | left: .75em; 49 | width: .5em; 50 | } 51 | 52 | 100% { 53 | top: 1.125em; 54 | left: .1875em; 55 | width: .75em; 56 | } 57 | } 58 | 59 | @keyframes swal2-toast-animate-success-line-long { 60 | 0% { 61 | top: 1.625em; 62 | right: 1.375em; 63 | width: 0; 64 | } 65 | 66 | 65% { 67 | top: 1.25em; 68 | right: .9375em; 69 | width: 0; 70 | } 71 | 72 | 84% { 73 | top: .9375em; 74 | right: 0; 75 | width: 1.125em; 76 | } 77 | 78 | 100% { 79 | top: .9375em; 80 | right: .1875em; 81 | width: 1.375em; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/scss/_toasts-body.scss: -------------------------------------------------------------------------------- 1 | @mixin sweetalert2-toasts-body() { 2 | &.swal2-toast-shown { 3 | .swal2-container { 4 | background-color: transparent; 5 | 6 | &.swal2-top { 7 | top: 0; 8 | right: auto; 9 | bottom: auto; 10 | left: 50%; 11 | transform: translateX(-50%); 12 | } 13 | 14 | &.swal2-top-end, 15 | &.swal2-top-right { 16 | top: 0; 17 | right: 0; 18 | bottom: auto; 19 | left: auto; 20 | } 21 | 22 | &.swal2-top-start, 23 | &.swal2-top-left { 24 | top: 0; 25 | right: auto; 26 | bottom: auto; 27 | left: 0; 28 | } 29 | 30 | &.swal2-center-start, 31 | &.swal2-center-left { 32 | top: 50%; 33 | right: auto; 34 | bottom: auto; 35 | left: 0; 36 | transform: translateY(-50%); 37 | } 38 | 39 | &.swal2-center { 40 | top: 50%; 41 | right: auto; 42 | bottom: auto; 43 | left: 50%; 44 | transform: translate(-50%, -50%); 45 | } 46 | 47 | &.swal2-center-end, 48 | &.swal2-center-right { 49 | top: 50%; 50 | right: 0; 51 | bottom: auto; 52 | left: auto; 53 | transform: translateY(-50%); 54 | } 55 | 56 | &.swal2-bottom-start, 57 | &.swal2-bottom-left { 58 | top: auto; 59 | right: auto; 60 | bottom: 0; 61 | left: 0; 62 | } 63 | 64 | &.swal2-bottom { 65 | top: auto; 66 | right: auto; 67 | bottom: 0; 68 | left: 50%; 69 | transform: translateX(-50%); 70 | } 71 | 72 | &.swal2-bottom-end, 73 | &.swal2-bottom-right { 74 | top: auto; 75 | right: 0; 76 | bottom: 0; 77 | left: auto; 78 | } 79 | } 80 | } 81 | 82 | &.swal2-toast-column { 83 | .swal2-toast { 84 | flex-direction: column; 85 | align-items: stretch; 86 | 87 | .swal2-actions { 88 | flex: 1; 89 | align-self: stretch; 90 | height: 2.2em; 91 | margin-top: .3125em; 92 | } 93 | 94 | .swal2-loading { 95 | justify-content: center; 96 | } 97 | 98 | .swal2-input { 99 | height: 2em; 100 | margin: .3125em auto; 101 | font-size: $swal2-toast-input-font-size; 102 | } 103 | 104 | .swal2-validation-message { 105 | font-size: $swal2-toast-validation-font-size; 106 | } 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/staticMethods.js: -------------------------------------------------------------------------------- 1 | export * from './staticMethods/argsToParams.js' 2 | export * from './staticMethods/dom.js' 3 | export * from './staticMethods/fire.js' 4 | export * from './staticMethods/mixin.js' 5 | export * from './staticMethods/queue.js' 6 | export * from './staticMethods/showLoading.js' 7 | export * from './staticMethods/timer.js' 8 | export { 9 | isValidParameter, 10 | isUpdatableParameter, 11 | isDeprecatedParameter 12 | } from './utils/params.js' 13 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/staticMethods/argsToParams.js: -------------------------------------------------------------------------------- 1 | import { error } from '../utils/utils.js' 2 | 3 | const isJqueryElement = (elem) => typeof elem === 'object' && elem.jquery 4 | const isElement = (elem) => elem instanceof Element || isJqueryElement(elem) 5 | 6 | export const argsToParams = (args) => { 7 | const params = {} 8 | if (typeof args[0] === 'object' && !isElement(args[0])) { 9 | Object.assign(params, args[0]) 10 | } else { 11 | ['title', 'html', 'icon'].forEach((name, index) => { 12 | const arg = args[index] 13 | if (typeof arg === 'string' || isElement(arg)) { 14 | params[name] = arg 15 | } else if (arg !== undefined) { 16 | error(`Unexpected type of ${name}! Expected "string" or "Element", got ${typeof arg}`) 17 | } 18 | }) 19 | } 20 | return params 21 | } 22 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/staticMethods/dom.js: -------------------------------------------------------------------------------- 1 | import * as dom from '../utils/dom/index.js' 2 | import * as domUtils from '../utils/dom/domUtils.js' 3 | 4 | export { 5 | getContainer, 6 | getPopup, 7 | getTitle, 8 | getContent, 9 | getHtmlContainer, 10 | getImage, 11 | getIcon, 12 | getIcons, 13 | getCloseButton, 14 | getActions, 15 | getConfirmButton, 16 | getDenyButton, 17 | getCancelButton, 18 | getHeader, 19 | getFooter, 20 | getTimerProgressBar, 21 | getFocusableElements, 22 | getValidationMessage, 23 | isLoading 24 | } from '../utils/dom/index.js' 25 | 26 | /* 27 | * Global function to determine if SweetAlert2 popup is shown 28 | */ 29 | export const isVisible = () => { 30 | return domUtils.isVisible(dom.getPopup()) 31 | } 32 | 33 | /* 34 | * Global function to click 'Confirm' button 35 | */ 36 | export const clickConfirm = () => dom.getConfirmButton() && dom.getConfirmButton().click() 37 | 38 | /* 39 | * Global function to click 'Deny' button 40 | */ 41 | export const clickDeny = () => dom.getDenyButton() && dom.getDenyButton().click() 42 | 43 | /* 44 | * Global function to click 'Cancel' button 45 | */ 46 | export const clickCancel = () => dom.getCancelButton() && dom.getCancelButton().click() 47 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/staticMethods/fire.js: -------------------------------------------------------------------------------- 1 | export function fire (...args) { 2 | const Swal = this 3 | return new Swal(...args) 4 | } 5 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/staticMethods/mixin.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Returns an extended version of `Swal` containing `params` as defaults. 3 | * Useful for reusing Swal configuration. 4 | * 5 | * For example: 6 | * 7 | * Before: 8 | * const textPromptOptions = { input: 'text', showCancelButton: true } 9 | * const {value: firstName} = await Swal.fire({ ...textPromptOptions, title: 'What is your first name?' }) 10 | * const {value: lastName} = await Swal.fire({ ...textPromptOptions, title: 'What is your last name?' }) 11 | * 12 | * After: 13 | * const TextPrompt = Swal.mixin({ input: 'text', showCancelButton: true }) 14 | * const {value: firstName} = await TextPrompt('What is your first name?') 15 | * const {value: lastName} = await TextPrompt('What is your last name?') 16 | * 17 | * @param mixinParams 18 | */ 19 | export function mixin (mixinParams) { 20 | class MixinSwal extends this { 21 | _main (params) { 22 | return super._main(Object.assign({}, mixinParams, params)) 23 | } 24 | } 25 | 26 | return MixinSwal 27 | } 28 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/staticMethods/queue.js: -------------------------------------------------------------------------------- 1 | import * as dom from '../utils/dom/index.js' 2 | 3 | // private global state for the queue feature 4 | let currentSteps = [] 5 | 6 | /* 7 | * Global function for chaining sweetAlert popups 8 | */ 9 | export const queue = function (steps) { 10 | const Swal = this 11 | currentSteps = steps 12 | 13 | const resetAndResolve = (resolve, value) => { 14 | currentSteps = [] 15 | resolve(value) 16 | } 17 | 18 | const queueResult = [] 19 | return new Promise((resolve) => { 20 | (function step (i, callback) { 21 | if (i < currentSteps.length) { 22 | document.body.setAttribute('data-swal2-queue-step', i) 23 | Swal.fire(currentSteps[i]).then((result) => { 24 | if (typeof result.value !== 'undefined') { 25 | queueResult.push(result.value) 26 | step(i + 1, callback) 27 | } else { 28 | resetAndResolve(resolve, { dismiss: result.dismiss }) 29 | } 30 | }) 31 | } else { 32 | resetAndResolve(resolve, { value: queueResult }) 33 | } 34 | })(0) 35 | }) 36 | } 37 | 38 | /* 39 | * Global function for getting the index of current popup in queue 40 | */ 41 | export const getQueueStep = () => dom.getContainer() && dom.getContainer().getAttribute('data-queue-step') 42 | 43 | /* 44 | * Global function for inserting a popup to the queue 45 | */ 46 | export const insertQueueStep = (step, index) => { 47 | if (index && index < currentSteps.length) { 48 | return currentSteps.splice(index, 0, step) 49 | } 50 | return currentSteps.push(step) 51 | } 52 | 53 | /* 54 | * Global function for deleting a popup from the queue 55 | */ 56 | export const deleteQueueStep = (index) => { 57 | if (typeof currentSteps[index] !== 'undefined') { 58 | currentSteps.splice(index, 1) 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/staticMethods/showLoading.js: -------------------------------------------------------------------------------- 1 | import * as dom from '../utils/dom/index.js' 2 | import Swal from '../sweetalert2.js' 3 | import { swalClasses } from '../utils/classes.js' 4 | 5 | /** 6 | * Show spinner instead of Confirm button 7 | */ 8 | const showLoading = () => { 9 | let popup = dom.getPopup() 10 | if (!popup) { 11 | Swal.fire() 12 | } 13 | popup = dom.getPopup() 14 | const actions = dom.getActions() 15 | const confirmButton = dom.getConfirmButton() 16 | const loader = dom.getLoader() 17 | 18 | dom.show(actions) 19 | dom.hide(confirmButton) 20 | dom.addClass([popup, actions], swalClasses.loading) 21 | 22 | dom.show(loader) 23 | 24 | popup.setAttribute('data-loading', true) 25 | popup.setAttribute('aria-busy', true) 26 | popup.focus() 27 | } 28 | 29 | export { 30 | showLoading, 31 | showLoading as enableLoading 32 | } 33 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/staticMethods/timer.js: -------------------------------------------------------------------------------- 1 | import { animateTimerProgressBar, stopTimerProgressBar } from '../utils/dom/domUtils.js' 2 | import globalState from '../globalState.js' 3 | 4 | /** 5 | * If `timer` parameter is set, returns number of milliseconds of timer remained. 6 | * Otherwise, returns undefined. 7 | */ 8 | export const getTimerLeft = () => { 9 | return globalState.timeout && globalState.timeout.getTimerLeft() 10 | } 11 | 12 | /** 13 | * Stop timer. Returns number of milliseconds of timer remained. 14 | * If `timer` parameter isn't set, returns undefined. 15 | */ 16 | export const stopTimer = () => { 17 | if (globalState.timeout) { 18 | stopTimerProgressBar() 19 | return globalState.timeout.stop() 20 | } 21 | } 22 | 23 | /** 24 | * Resume timer. Returns number of milliseconds of timer remained. 25 | * If `timer` parameter isn't set, returns undefined. 26 | */ 27 | export const resumeTimer = () => { 28 | if (globalState.timeout) { 29 | const remaining = globalState.timeout.start() 30 | animateTimerProgressBar(remaining) 31 | return remaining 32 | } 33 | } 34 | 35 | /** 36 | * Resume timer. Returns number of milliseconds of timer remained. 37 | * If `timer` parameter isn't set, returns undefined. 38 | */ 39 | export const toggleTimer = () => { 40 | const timer = globalState.timeout 41 | return timer && (timer.running ? stopTimer() : resumeTimer()) 42 | } 43 | 44 | /** 45 | * Increase timer. Returns number of milliseconds of an updated timer. 46 | * If `timer` parameter isn't set, returns undefined. 47 | */ 48 | export const increaseTimer = (n) => { 49 | if (globalState.timeout) { 50 | const remaining = globalState.timeout.increase(n) 51 | animateTimerProgressBar(remaining, true) 52 | return remaining 53 | } 54 | } 55 | 56 | /** 57 | * Check if timer is running. Returns true if timer is running 58 | * or false if timer is paused or stopped. 59 | * If `timer` parameter isn't set, returns undefined 60 | */ 61 | export const isTimerRunning = () => { 62 | return globalState.timeout && globalState.timeout.isRunning() 63 | } 64 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/sweetalert2.js: -------------------------------------------------------------------------------- 1 | import SweetAlert from './SweetAlert.js' 2 | 3 | const Swal = SweetAlert 4 | Swal.default = Swal 5 | 6 | export default Swal 7 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/sweetalert2.scss: -------------------------------------------------------------------------------- 1 | // SweetAlert2 2 | // github.com/sweetalert2/sweetalert2 3 | 4 | @import 'scss/theming'; 5 | @import 'scss/polyfills'; 6 | @import 'scss/animations'; 7 | 8 | body { 9 | @include sweetalert2-body(); 10 | @include sweetalert2-toasts-body(); 11 | } 12 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/utils/DismissReason.js: -------------------------------------------------------------------------------- 1 | export const DismissReason = Object.freeze({ 2 | cancel: 'cancel', 3 | backdrop: 'backdrop', 4 | close: 'close', 5 | esc: 'esc', 6 | timer: 'timer' 7 | }) 8 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/utils/Timer.js: -------------------------------------------------------------------------------- 1 | export default class Timer { 2 | constructor (callback, delay) { 3 | this.callback = callback 4 | this.remaining = delay 5 | this.running = false 6 | 7 | this.start() 8 | } 9 | 10 | start () { 11 | if (!this.running) { 12 | this.running = true 13 | this.started = new Date() 14 | this.id = setTimeout(this.callback, this.remaining) 15 | } 16 | return this.remaining 17 | } 18 | 19 | stop () { 20 | if (this.running) { 21 | this.running = false 22 | clearTimeout(this.id) 23 | this.remaining -= new Date() - this.started 24 | } 25 | return this.remaining 26 | } 27 | 28 | increase (n) { 29 | const running = this.running 30 | if (running) { 31 | this.stop() 32 | } 33 | this.remaining += n 34 | if (running) { 35 | this.start() 36 | } 37 | return this.remaining 38 | } 39 | 40 | getTimerLeft () { 41 | if (this.running) { 42 | this.stop() 43 | this.start() 44 | } 45 | return this.remaining 46 | } 47 | 48 | isRunning () { 49 | return this.running 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/utils/aria.js: -------------------------------------------------------------------------------- 1 | import { getContainer } from './dom/getters.js' 2 | import { contains } from './dom/domUtils.js' 3 | import { toArray } from './utils.js' 4 | 5 | // From https://developer.paciellogroup.com/blog/2018/06/the-current-state-of-modal-dialog-accessibility/ 6 | // Adding aria-hidden="true" to elements outside of the active modal dialog ensures that 7 | // elements not within the active modal dialog will not be surfaced if a user opens a screen 8 | // reader’s list of elements (headings, form controls, landmarks, etc.) in the document. 9 | 10 | export const setAriaHidden = () => { 11 | const bodyChildren = toArray(document.body.children) 12 | bodyChildren.forEach(el => { 13 | if (el === getContainer() || contains(el, getContainer())) { 14 | return 15 | } 16 | 17 | if (el.hasAttribute('aria-hidden')) { 18 | el.setAttribute('data-previous-aria-hidden', el.getAttribute('aria-hidden')) 19 | } 20 | el.setAttribute('aria-hidden', 'true') 21 | }) 22 | } 23 | 24 | export const unsetAriaHidden = () => { 25 | const bodyChildren = toArray(document.body.children) 26 | bodyChildren.forEach(el => { 27 | if (el.hasAttribute('data-previous-aria-hidden')) { 28 | el.setAttribute('aria-hidden', el.getAttribute('data-previous-aria-hidden')) 29 | el.removeAttribute('data-previous-aria-hidden') 30 | } else { 31 | el.removeAttribute('aria-hidden') 32 | } 33 | }) 34 | } 35 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/utils/classes.js: -------------------------------------------------------------------------------- 1 | export const swalPrefix = 'swal2-' 2 | 3 | export const prefix = (items) => { 4 | const result = {} 5 | for (const i in items) { 6 | result[items[i]] = swalPrefix + items[i] 7 | } 8 | return result 9 | } 10 | 11 | export const swalClasses = prefix([ 12 | 'container', 13 | 'shown', 14 | 'height-auto', 15 | 'iosfix', 16 | 'popup', 17 | 'modal', 18 | 'no-backdrop', 19 | 'no-transition', 20 | 'toast', 21 | 'toast-shown', 22 | 'toast-column', 23 | 'show', 24 | 'hide', 25 | 'close', 26 | 'title', 27 | 'header', 28 | 'content', 29 | 'html-container', 30 | 'actions', 31 | 'confirm', 32 | 'deny', 33 | 'cancel', 34 | 'footer', 35 | 'icon', 36 | 'icon-content', 37 | 'image', 38 | 'input', 39 | 'file', 40 | 'range', 41 | 'select', 42 | 'radio', 43 | 'checkbox', 44 | 'label', 45 | 'textarea', 46 | 'inputerror', 47 | 'validation-message', 48 | 'progress-steps', 49 | 'active-progress-step', 50 | 'progress-step', 51 | 'progress-step-line', 52 | 'loader', 53 | 'loading', 54 | 'styled', 55 | 'top', 56 | 'top-start', 57 | 'top-end', 58 | 'top-left', 59 | 'top-right', 60 | 'center', 61 | 'center-start', 62 | 'center-end', 63 | 'center-left', 64 | 'center-right', 65 | 'bottom', 66 | 'bottom-start', 67 | 'bottom-end', 68 | 'bottom-left', 69 | 'bottom-right', 70 | 'grow-row', 71 | 'grow-column', 72 | 'grow-fullscreen', 73 | 'rtl', 74 | 'timer-progress-bar', 75 | 'timer-progress-bar-container', 76 | 'scrollbar-measure', 77 | 'icon-success', 78 | 'icon-warning', 79 | 'icon-info', 80 | 'icon-question', 81 | 'icon-error', 82 | ]) 83 | 84 | export const iconTypes = prefix([ 85 | 'success', 86 | 'warning', 87 | 'info', 88 | 'question', 89 | 'error' 90 | ]) 91 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/utils/defaultInputValidators.js: -------------------------------------------------------------------------------- 1 | export default { 2 | email: (string, validationMessage) => { 3 | return /^[a-zA-Z0-9.+_-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9-]{2,24}$/.test(string) 4 | ? Promise.resolve() 5 | : Promise.resolve(validationMessage || 'Invalid email address') 6 | }, 7 | url: (string, validationMessage) => { 8 | // taken from https://stackoverflow.com/a/3809435 with a small change from #1306 and #2013 9 | return /^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-z]{2,63}\b([-a-zA-Z0-9@:%_+.~#?&/=]*)$/.test(string) 10 | ? Promise.resolve() 11 | : Promise.resolve(validationMessage || 'Invalid URL') 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/utils/dom/animationEndEvent.js: -------------------------------------------------------------------------------- 1 | import { isNodeEnv } from '../isNodeEnv.js' 2 | 3 | export const animationEndEvent = (() => { 4 | // Prevent run in Node env 5 | /* istanbul ignore if */ 6 | if (isNodeEnv()) { 7 | return false 8 | } 9 | 10 | const testEl = document.createElement('div') 11 | const transEndEventNames = { 12 | WebkitAnimation: 'webkitAnimationEnd', 13 | OAnimation: 'oAnimationEnd oanimationend', 14 | animation: 'animationend' 15 | } 16 | for (const i in transEndEventNames) { 17 | if (Object.prototype.hasOwnProperty.call(transEndEventNames, i) && typeof testEl.style[i] !== 'undefined') { 18 | return transEndEventNames[i] 19 | } 20 | } 21 | 22 | return false 23 | })() 24 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/utils/dom/getters.js: -------------------------------------------------------------------------------- 1 | import { swalClasses } from '../classes.js' 2 | import { uniqueArray, toArray } from '../utils.js' 3 | import { isVisible } from './domUtils.js' 4 | 5 | export const getContainer = () => document.body.querySelector(`.${swalClasses.container}`) 6 | 7 | export const elementBySelector = (selectorString) => { 8 | const container = getContainer() 9 | return container ? container.querySelector(selectorString) : null 10 | } 11 | 12 | const elementByClass = (className) => { 13 | return elementBySelector(`.${className}`) 14 | } 15 | 16 | export const getPopup = () => elementByClass(swalClasses.popup) 17 | 18 | export const getIcons = () => { 19 | const popup = getPopup() 20 | return toArray(popup.querySelectorAll(`.${swalClasses.icon}`)) 21 | } 22 | 23 | export const getIcon = () => { 24 | const visibleIcon = getIcons().filter((icon) => isVisible(icon)) 25 | return visibleIcon.length ? visibleIcon[0] : null 26 | } 27 | 28 | export const getTitle = () => elementByClass(swalClasses.title) 29 | 30 | export const getContent = () => elementByClass(swalClasses.content) 31 | 32 | export const getHtmlContainer = () => elementByClass(swalClasses['html-container']) 33 | 34 | export const getImage = () => elementByClass(swalClasses.image) 35 | 36 | export const getProgressSteps = () => elementByClass(swalClasses['progress-steps']) 37 | 38 | export const getValidationMessage = () => elementByClass(swalClasses['validation-message']) 39 | 40 | export const getConfirmButton = () => elementBySelector(`.${swalClasses.actions} .${swalClasses.confirm}`) 41 | 42 | export const getDenyButton = () => elementBySelector(`.${swalClasses.actions} .${swalClasses.deny}`) 43 | 44 | export const getLoader = () => elementBySelector(`.${swalClasses.loader}`) 45 | 46 | export const getCancelButton = () => elementBySelector(`.${swalClasses.actions} .${swalClasses.cancel}`) 47 | 48 | export const getActions = () => elementByClass(swalClasses.actions) 49 | 50 | export const getHeader = () => elementByClass(swalClasses.header) 51 | 52 | export const getFooter = () => elementByClass(swalClasses.footer) 53 | 54 | export const getTimerProgressBar = () => elementByClass(swalClasses['timer-progress-bar']) 55 | 56 | export const getCloseButton = () => elementByClass(swalClasses.close) 57 | 58 | // https://github.com/jkup/focusable/blob/master/index.js 59 | const focusable = ` 60 | a[href], 61 | area[href], 62 | input:not([disabled]), 63 | select:not([disabled]), 64 | textarea:not([disabled]), 65 | button:not([disabled]), 66 | iframe, 67 | object, 68 | embed, 69 | [tabindex="0"], 70 | [contenteditable], 71 | audio[controls], 72 | video[controls], 73 | summary 74 | ` 75 | 76 | export const getFocusableElements = () => { 77 | const focusableElementsWithTabindex = toArray( 78 | getPopup().querySelectorAll('[tabindex]:not([tabindex="-1"]):not([tabindex="0"])') 79 | ) 80 | // sort according to tabindex 81 | .sort((a, b) => { 82 | a = parseInt(a.getAttribute('tabindex')) 83 | b = parseInt(b.getAttribute('tabindex')) 84 | if (a > b) { 85 | return 1 86 | } else if (a < b) { 87 | return -1 88 | } 89 | return 0 90 | }) 91 | 92 | const otherFocusableElements = toArray( 93 | getPopup().querySelectorAll(focusable) 94 | ).filter(el => el.getAttribute('tabindex') !== '-1') 95 | 96 | return uniqueArray(focusableElementsWithTabindex.concat(otherFocusableElements)).filter(el => isVisible(el)) 97 | } 98 | 99 | export const isModal = () => { 100 | return !isToast() && !document.body.classList.contains(swalClasses['no-backdrop']) 101 | } 102 | 103 | export const isToast = () => { 104 | return document.body.classList.contains(swalClasses['toast-shown']) 105 | } 106 | 107 | export const isLoading = () => { 108 | return getPopup().hasAttribute('data-loading') 109 | } 110 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/utils/dom/index.js: -------------------------------------------------------------------------------- 1 | export * from './domUtils.js' 2 | export * from './init.js' 3 | export * from './getters.js' 4 | export * from './parseHtmlToContainer.js' 5 | export * from './animationEndEvent.js' 6 | export * from './measureScrollbar.js' 7 | export * from './renderers/render.js' 8 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/utils/dom/measureScrollbar.js: -------------------------------------------------------------------------------- 1 | import { swalClasses } from '../classes.js' 2 | 3 | // Measure scrollbar width for padding body during modal show/hide 4 | // https://github.com/twbs/bootstrap/blob/master/js/src/modal.js 5 | export const measureScrollbar = () => { 6 | const scrollDiv = document.createElement('div') 7 | scrollDiv.className = swalClasses['scrollbar-measure'] 8 | document.body.appendChild(scrollDiv) 9 | const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth 10 | document.body.removeChild(scrollDiv) 11 | return scrollbarWidth 12 | } 13 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/utils/dom/parseHtmlToContainer.js: -------------------------------------------------------------------------------- 1 | import { setInnerHtml } from './domUtils.js' 2 | 3 | export const parseHtmlToContainer = (param, target) => { 4 | // DOM element 5 | if (param instanceof HTMLElement) { 6 | target.appendChild(param) 7 | 8 | // Object 9 | } else if (typeof param === 'object') { 10 | handleObject(param, target) 11 | 12 | // Plain string 13 | } else if (param) { 14 | setInnerHtml(target, param) 15 | } 16 | } 17 | 18 | const handleObject = (param, target) => { 19 | // JQuery element(s) 20 | if (param.jquery) { 21 | handleJqueryElem(target, param) 22 | 23 | // For other objects use their string representation 24 | } else { 25 | setInnerHtml(target, param.toString()) 26 | } 27 | } 28 | 29 | const handleJqueryElem = (target, elem) => { 30 | target.textContent = '' 31 | if (0 in elem) { 32 | for (let i = 0; i in elem; i++) { 33 | target.appendChild(elem[i].cloneNode(true)) 34 | } 35 | } else { 36 | target.appendChild(elem.cloneNode(true)) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/utils/dom/renderers/render.js: -------------------------------------------------------------------------------- 1 | import { getPopup } from '../getters.js' 2 | import { renderActions } from './renderActions.js' 3 | import { renderContainer } from './renderContainer.js' 4 | import { renderContent } from './renderContent.js' 5 | import { renderFooter } from './renderFooter.js' 6 | import { renderHeader } from './renderHeader.js' 7 | import { renderPopup } from './renderPopup.js' 8 | 9 | export const render = (instance, params) => { 10 | renderPopup(instance, params) 11 | renderContainer(instance, params) 12 | 13 | renderHeader(instance, params) 14 | renderContent(instance, params) 15 | renderActions(instance, params) 16 | renderFooter(instance, params) 17 | 18 | if (typeof params.didRender === 'function') { 19 | params.didRender(getPopup()) 20 | } else if (typeof params.onRender === 'function') { 21 | params.onRender(getPopup()) // @deprecated 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/utils/dom/renderers/renderActions.js: -------------------------------------------------------------------------------- 1 | import { swalClasses } from '../../classes.js' 2 | import * as dom from '../../dom/index.js' 3 | import { capitalizeFirstLetter } from '../../utils.js' 4 | import { isLoading } from '../getters.js' 5 | 6 | export const renderActions = (instance, params) => { 7 | const actions = dom.getActions() 8 | const loader = dom.getLoader() 9 | const confirmButton = dom.getConfirmButton() 10 | const denyButton = dom.getDenyButton() 11 | const cancelButton = dom.getCancelButton() 12 | 13 | // Actions (buttons) wrapper 14 | if (!params.showConfirmButton && !params.showDenyButton && !params.showCancelButton) { 15 | dom.hide(actions) 16 | } 17 | 18 | // Custom class 19 | dom.applyCustomClass(actions, params, 'actions') 20 | 21 | // Render buttons 22 | renderButton(confirmButton, 'confirm', params) 23 | renderButton(denyButton, 'deny', params) 24 | renderButton(cancelButton, 'cancel', params) 25 | 26 | // Loader 27 | loader.innerHTML = params.loaderHtml 28 | 29 | if (params.buttonsStyling) { 30 | handleButtonsStyling(confirmButton, denyButton, cancelButton, params) 31 | } else { 32 | dom.removeClass([confirmButton, denyButton, cancelButton], swalClasses.styled) 33 | } 34 | 35 | if (params.reverseButtons) { 36 | actions.insertBefore(cancelButton, loader) 37 | actions.insertBefore(denyButton, loader) 38 | actions.insertBefore(confirmButton, loader) 39 | } 40 | } 41 | 42 | function handleButtonsStyling (confirmButton, denyButton, cancelButton, params) { 43 | dom.addClass([confirmButton, denyButton, cancelButton], swalClasses.styled) 44 | 45 | // Buttons background colors 46 | if (params.confirmButtonColor) { 47 | confirmButton.style.backgroundColor = params.confirmButtonColor 48 | } 49 | if (params.denyButtonColor) { 50 | denyButton.style.backgroundColor = params.denyButtonColor 51 | } 52 | if (params.cancelButtonColor) { 53 | cancelButton.style.backgroundColor = params.cancelButtonColor 54 | } 55 | 56 | // Loading state 57 | if (!isLoading()) { 58 | const confirmButtonBackgroundColor = window.getComputedStyle(confirmButton).getPropertyValue('background-color') 59 | confirmButton.style.borderLeftColor = confirmButtonBackgroundColor 60 | confirmButton.style.borderRightColor = confirmButtonBackgroundColor 61 | } 62 | } 63 | 64 | function renderButton (button, buttonType, params) { 65 | dom.toggle(button, params[`show${capitalizeFirstLetter(buttonType)}Button`], 'inline-block') 66 | dom.setInnerHtml(button, params[`${buttonType}ButtonText`]) // Set caption text 67 | button.setAttribute('aria-label', params[`${buttonType}ButtonAriaLabel`]) // ARIA label 68 | 69 | // Add buttons custom classes 70 | button.className = swalClasses[buttonType] 71 | dom.applyCustomClass(button, params, `${buttonType}Button`) 72 | dom.addClass(button, params[`${buttonType}ButtonClass`]) 73 | } 74 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/utils/dom/renderers/renderCloseButton.js: -------------------------------------------------------------------------------- 1 | import * as dom from '../../dom/index.js' 2 | 3 | export const renderCloseButton = (instance, params) => { 4 | const closeButton = dom.getCloseButton() 5 | 6 | dom.setInnerHtml(closeButton, params.closeButtonHtml) 7 | 8 | // Custom class 9 | dom.applyCustomClass(closeButton, params, 'closeButton') 10 | 11 | dom.toggle(closeButton, params.showCloseButton) 12 | closeButton.setAttribute('aria-label', params.closeButtonAriaLabel) 13 | } 14 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/utils/dom/renderers/renderContainer.js: -------------------------------------------------------------------------------- 1 | import { swalClasses } from '../../classes.js' 2 | import { warn } from '../../utils.js' 3 | import * as dom from '../../dom/index.js' 4 | 5 | function handleBackdropParam (container, backdrop) { 6 | if (typeof backdrop === 'string') { 7 | container.style.background = backdrop 8 | } else if (!backdrop) { 9 | dom.addClass([document.documentElement, document.body], swalClasses['no-backdrop']) 10 | } 11 | } 12 | 13 | function handlePositionParam (container, position) { 14 | if (position in swalClasses) { 15 | dom.addClass(container, swalClasses[position]) 16 | } else { 17 | warn('The "position" parameter is not valid, defaulting to "center"') 18 | dom.addClass(container, swalClasses.center) 19 | } 20 | } 21 | 22 | function handleGrowParam (container, grow) { 23 | if (grow && typeof grow === 'string') { 24 | const growClass = `grow-${grow}` 25 | if (growClass in swalClasses) { 26 | dom.addClass(container, swalClasses[growClass]) 27 | } 28 | } 29 | } 30 | 31 | export const renderContainer = (instance, params) => { 32 | const container = dom.getContainer() 33 | 34 | if (!container) { 35 | return 36 | } 37 | 38 | handleBackdropParam(container, params.backdrop) 39 | 40 | if (!params.backdrop && params.allowOutsideClick) { 41 | warn('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`') 42 | } 43 | 44 | handlePositionParam(container, params.position) 45 | handleGrowParam(container, params.grow) 46 | 47 | // Custom class 48 | dom.applyCustomClass(container, params, 'container') 49 | 50 | // Set queue step attribute for getQueueStep() method 51 | const queueStep = document.body.getAttribute('data-swal2-queue-step') 52 | if (queueStep) { 53 | container.setAttribute('data-queue-step', queueStep) 54 | document.body.removeAttribute('data-swal2-queue-step') 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/utils/dom/renderers/renderContent.js: -------------------------------------------------------------------------------- 1 | import { swalClasses } from '../../classes.js' 2 | import * as dom from '../../dom/index.js' 3 | import { renderInput } from './renderInput.js' 4 | 5 | export const renderContent = (instance, params) => { 6 | const content = dom.getContent().querySelector(`#${swalClasses.content}`) 7 | 8 | // Content as HTML 9 | if (params.html) { 10 | dom.parseHtmlToContainer(params.html, content) 11 | dom.show(content, 'block') 12 | 13 | // Content as plain text 14 | } else if (params.text) { 15 | content.textContent = params.text 16 | dom.show(content, 'block') 17 | 18 | // No content 19 | } else { 20 | dom.hide(content) 21 | } 22 | 23 | renderInput(instance, params) 24 | 25 | // Custom class 26 | dom.applyCustomClass(dom.getContent(), params, 'content') 27 | } 28 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/utils/dom/renderers/renderFooter.js: -------------------------------------------------------------------------------- 1 | import * as dom from '../../dom/index.js' 2 | 3 | export const renderFooter = (instance, params) => { 4 | const footer = dom.getFooter() 5 | 6 | dom.toggle(footer, params.footer) 7 | 8 | if (params.footer) { 9 | dom.parseHtmlToContainer(params.footer, footer) 10 | } 11 | 12 | // Custom class 13 | dom.applyCustomClass(footer, params, 'footer') 14 | } 15 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/utils/dom/renderers/renderHeader.js: -------------------------------------------------------------------------------- 1 | import * as dom from '../../dom/index.js' 2 | import { renderCloseButton } from './renderCloseButton.js' 3 | import { renderIcon } from './renderIcon.js' 4 | import { renderImage } from './renderImage.js' 5 | import { renderProgressSteps } from './renderProgressSteps.js' 6 | import { renderTitle } from './renderTitle.js' 7 | 8 | export const renderHeader = (instance, params) => { 9 | const header = dom.getHeader() 10 | 11 | // Custom class 12 | dom.applyCustomClass(header, params, 'header') 13 | 14 | // Progress steps 15 | renderProgressSteps(instance, params) 16 | 17 | // Icon 18 | renderIcon(instance, params) 19 | 20 | // Image 21 | renderImage(instance, params) 22 | 23 | // Title 24 | renderTitle(instance, params) 25 | 26 | // Close button 27 | renderCloseButton(instance, params) 28 | } 29 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/utils/dom/renderers/renderIcon.js: -------------------------------------------------------------------------------- 1 | import { swalClasses, iconTypes } from '../../classes.js' 2 | import { error } from '../../utils.js' 3 | import * as dom from '../../dom/index.js' 4 | import privateProps from '../../../privateProps.js' 5 | 6 | export const renderIcon = (instance, params) => { 7 | const innerParams = privateProps.innerParams.get(instance) 8 | 9 | // if the given icon already rendered, apply the styling without re-rendering the icon 10 | if (innerParams && params.icon === innerParams.icon && dom.getIcon()) { 11 | applyStyles(dom.getIcon(), params) 12 | return 13 | } 14 | 15 | hideAllIcons() 16 | 17 | if (!params.icon) { 18 | return 19 | } 20 | 21 | if (Object.keys(iconTypes).indexOf(params.icon) !== -1) { 22 | const icon = dom.elementBySelector(`.${swalClasses.icon}.${iconTypes[params.icon]}`) 23 | dom.show(icon) 24 | 25 | // Custom or default content 26 | setContent(icon, params) 27 | 28 | applyStyles(icon, params) 29 | 30 | // Animate icon 31 | dom.addClass(icon, params.showClass.icon) 32 | } else { 33 | error(`Unknown icon! Expected "success", "error", "warning", "info" or "question", got "${params.icon}"`) 34 | } 35 | } 36 | 37 | const hideAllIcons = () => { 38 | const icons = dom.getIcons() 39 | for (let i = 0; i < icons.length; i++) { 40 | dom.hide(icons[i]) 41 | } 42 | } 43 | 44 | const applyStyles = (icon, params) => { 45 | // Icon color 46 | setColor(icon, params) 47 | 48 | // Success icon background color 49 | adjustSuccessIconBackgoundColor() 50 | 51 | // Custom class 52 | dom.applyCustomClass(icon, params, 'icon') 53 | } 54 | 55 | // Adjust success icon background color to match the popup background color 56 | const adjustSuccessIconBackgoundColor = () => { 57 | const popup = dom.getPopup() 58 | const popupBackgroundColor = window.getComputedStyle(popup).getPropertyValue('background-color') 59 | const successIconParts = popup.querySelectorAll('[class^=swal2-success-circular-line], .swal2-success-fix') 60 | for (let i = 0; i < successIconParts.length; i++) { 61 | successIconParts[i].style.backgroundColor = popupBackgroundColor 62 | } 63 | } 64 | 65 | const setContent = (icon, params) => { 66 | icon.textContent = '' 67 | 68 | if (params.iconHtml) { 69 | dom.setInnerHtml(icon, iconContent(params.iconHtml)) 70 | } else if (params.icon === 'success') { 71 | dom.setInnerHtml(icon, ` 72 |
73 | 74 |
75 |
76 | `) 77 | } else if (params.icon === 'error') { 78 | dom.setInnerHtml(icon, ` 79 | 80 | 81 | 82 | 83 | `) 84 | } else { 85 | const defaultIconHtml = { 86 | question: '?', 87 | warning: '!', 88 | info: 'i' 89 | } 90 | dom.setInnerHtml(icon, iconContent(defaultIconHtml[params.icon])) 91 | } 92 | } 93 | 94 | const setColor = (icon, params) => { 95 | if (!params.iconColor) { 96 | return 97 | } 98 | icon.style.color = params.iconColor 99 | icon.style.borderColor = params.iconColor 100 | for (const sel of ['.swal2-success-line-tip', '.swal2-success-line-long', '.swal2-x-mark-line-left', '.swal2-x-mark-line-right']) { 101 | dom.setStyle(icon, sel, 'backgroundColor', params.iconColor) 102 | } 103 | dom.setStyle(icon, '.swal2-success-ring', 'borderColor', params.iconColor) 104 | } 105 | 106 | const iconContent = (content) => `
${content}
` 107 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/utils/dom/renderers/renderImage.js: -------------------------------------------------------------------------------- 1 | import { swalClasses } from '../../classes.js' 2 | import * as dom from '../../dom/index.js' 3 | 4 | export const renderImage = (instance, params) => { 5 | const image = dom.getImage() 6 | 7 | if (!params.imageUrl) { 8 | return dom.hide(image) 9 | } 10 | 11 | dom.show(image, '') 12 | 13 | // Src, alt 14 | image.setAttribute('src', params.imageUrl) 15 | image.setAttribute('alt', params.imageAlt) 16 | 17 | // Width, height 18 | dom.applyNumericalStyle(image, 'width', params.imageWidth) 19 | dom.applyNumericalStyle(image, 'height', params.imageHeight) 20 | 21 | // Class 22 | image.className = swalClasses.image 23 | dom.applyCustomClass(image, params, 'image') 24 | } 25 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/utils/dom/renderers/renderPopup.js: -------------------------------------------------------------------------------- 1 | import { swalClasses } from '../../classes.js' 2 | import * as dom from '../../dom/index.js' 3 | 4 | export const renderPopup = (instance, params) => { 5 | const popup = dom.getPopup() 6 | 7 | // Width 8 | dom.applyNumericalStyle(popup, 'width', params.width) 9 | 10 | // Padding 11 | dom.applyNumericalStyle(popup, 'padding', params.padding) 12 | 13 | // Background 14 | if (params.background) { 15 | popup.style.background = params.background 16 | } 17 | 18 | // Classes 19 | addClasses(popup, params) 20 | } 21 | 22 | const addClasses = (popup, params) => { 23 | // Default Class + showClass when updating Swal.update({}) 24 | popup.className = `${swalClasses.popup} ${dom.isVisible(popup) ? params.showClass.popup : ''}` 25 | 26 | if (params.toast) { 27 | dom.addClass([document.documentElement, document.body], swalClasses['toast-shown']) 28 | dom.addClass(popup, swalClasses.toast) 29 | } else { 30 | dom.addClass(popup, swalClasses.modal) 31 | } 32 | 33 | // Custom class 34 | dom.applyCustomClass(popup, params, 'popup') 35 | if (typeof params.customClass === 'string') { 36 | dom.addClass(popup, params.customClass) 37 | } 38 | 39 | // Icon class (#1842) 40 | if (params.icon) { 41 | dom.addClass(popup, swalClasses[`icon-${params.icon}`]) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/utils/dom/renderers/renderProgressSteps.js: -------------------------------------------------------------------------------- 1 | import { swalClasses } from '../../classes.js' 2 | import { warn } from '../../utils.js' 3 | import * as dom from '../../dom/index.js' 4 | import { getQueueStep } from '../../../staticMethods/queue.js' 5 | 6 | const createStepElement = (step) => { 7 | const stepEl = document.createElement('li') 8 | dom.addClass(stepEl, swalClasses['progress-step']) 9 | dom.setInnerHtml(stepEl, step) 10 | return stepEl 11 | } 12 | 13 | const createLineElement = (params) => { 14 | const lineEl = document.createElement('li') 15 | dom.addClass(lineEl, swalClasses['progress-step-line']) 16 | if (params.progressStepsDistance) { 17 | lineEl.style.width = params.progressStepsDistance 18 | } 19 | return lineEl 20 | } 21 | 22 | export const renderProgressSteps = (instance, params) => { 23 | const progressStepsContainer = dom.getProgressSteps() 24 | if (!params.progressSteps || params.progressSteps.length === 0) { 25 | return dom.hide(progressStepsContainer) 26 | } 27 | 28 | dom.show(progressStepsContainer) 29 | progressStepsContainer.textContent = '' 30 | const currentProgressStep = parseInt(params.currentProgressStep === undefined ? getQueueStep() : params.currentProgressStep) 31 | if (currentProgressStep >= params.progressSteps.length) { 32 | warn( 33 | 'Invalid currentProgressStep parameter, it should be less than progressSteps.length ' + 34 | '(currentProgressStep like JS arrays starts from 0)' 35 | ) 36 | } 37 | 38 | params.progressSteps.forEach((step, index) => { 39 | const stepEl = createStepElement(step) 40 | progressStepsContainer.appendChild(stepEl) 41 | if (index === currentProgressStep) { 42 | dom.addClass(stepEl, swalClasses['active-progress-step']) 43 | } 44 | 45 | if (index !== params.progressSteps.length - 1) { 46 | const lineEl = createLineElement(params) 47 | progressStepsContainer.appendChild(lineEl) 48 | } 49 | }) 50 | } 51 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/utils/dom/renderers/renderTitle.js: -------------------------------------------------------------------------------- 1 | import * as dom from '../../dom/index.js' 2 | 3 | export const renderTitle = (instance, params) => { 4 | const title = dom.getTitle() 5 | 6 | dom.toggle(title, params.title || params.titleText) 7 | 8 | if (params.title) { 9 | dom.parseHtmlToContainer(params.title, title) 10 | } 11 | 12 | if (params.titleText) { 13 | title.innerText = params.titleText 14 | } 15 | 16 | // Custom class 17 | dom.applyCustomClass(title, params, 'title') 18 | } 19 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/utils/ieFix.js: -------------------------------------------------------------------------------- 1 | /* istanbul ignore file */ 2 | import * as dom from './dom/index.js' 3 | 4 | // https://stackoverflow.com/a/21825207 5 | const isIE11 = () => !!window.MSInputMethodContext && !!document.documentMode 6 | 7 | // Fix IE11 centering sweetalert2/issues/933 8 | const fixVerticalPositionIE = () => { 9 | const container = dom.getContainer() 10 | const popup = dom.getPopup() 11 | 12 | container.style.removeProperty('align-items') 13 | if (popup.offsetTop < 0) { 14 | container.style.alignItems = 'flex-start' 15 | } 16 | } 17 | 18 | export const IEfix = () => { 19 | if (typeof window !== 'undefined' && isIE11()) { 20 | fixVerticalPositionIE() 21 | window.addEventListener('resize', fixVerticalPositionIE) 22 | } 23 | } 24 | 25 | export const undoIEfix = () => { 26 | if (typeof window !== 'undefined' && isIE11()) { 27 | window.removeEventListener('resize', fixVerticalPositionIE) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/utils/iosFix.js: -------------------------------------------------------------------------------- 1 | /* istanbul ignore file */ 2 | import * as dom from './dom/index.js' 3 | import { swalClasses } from '../utils/classes.js' 4 | 5 | // Fix iOS scrolling http://stackoverflow.com/q/39626302 6 | 7 | export const iOSfix = () => { 8 | const iOS = (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1) 9 | if (iOS && !dom.hasClass(document.body, swalClasses.iosfix)) { 10 | const offset = document.body.scrollTop 11 | document.body.style.top = `${offset * -1}px` 12 | dom.addClass(document.body, swalClasses.iosfix) 13 | lockBodyScroll() 14 | addBottomPaddingForTallPopups() // #1948 15 | } 16 | } 17 | 18 | const addBottomPaddingForTallPopups = () => { 19 | const safari = !navigator.userAgent.match(/(CriOS|FxiOS|EdgiOS|YaBrowser|UCBrowser)/i) 20 | if (safari) { 21 | const bottomPanelHeight = 44 22 | if (dom.getPopup().scrollHeight > window.innerHeight - bottomPanelHeight) { 23 | dom.getContainer().style.paddingBottom = `${bottomPanelHeight}px` 24 | } 25 | } 26 | } 27 | 28 | const lockBodyScroll = () => { // #1246 29 | const container = dom.getContainer() 30 | let preventTouchMove 31 | container.ontouchstart = (e) => { 32 | preventTouchMove = shouldPreventTouchMove(e.target) 33 | } 34 | container.ontouchmove = (e) => { 35 | if (preventTouchMove) { 36 | e.preventDefault() 37 | e.stopPropagation() 38 | } 39 | } 40 | } 41 | 42 | const shouldPreventTouchMove = (target) => { 43 | const container = dom.getContainer() 44 | if (target === container) { 45 | return true 46 | } 47 | if ( 48 | !dom.isScrollable(container) && 49 | target.tagName !== 'INPUT' && // #1603 50 | !( 51 | dom.isScrollable(dom.getContent()) && // #1944 52 | dom.getContent().contains(target) 53 | ) 54 | ) { 55 | return true 56 | } 57 | return false 58 | } 59 | 60 | export const undoIOSfix = () => { 61 | if (dom.hasClass(document.body, swalClasses.iosfix)) { 62 | const offset = parseInt(document.body.style.top, 10) 63 | dom.removeClass(document.body, swalClasses.iosfix) 64 | document.body.style.top = '' 65 | document.body.scrollTop = (offset * -1) 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/utils/isNodeEnv.js: -------------------------------------------------------------------------------- 1 | // Detect Node env 2 | export const isNodeEnv = () => typeof window === 'undefined' || typeof document === 'undefined' 3 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/utils/openPopup.js: -------------------------------------------------------------------------------- 1 | import * as dom from './dom/index.js' 2 | import { swalClasses } from './classes.js' 3 | import { fixScrollbar } from './scrollbarFix.js' 4 | import { iOSfix } from './iosFix.js' 5 | import { IEfix } from './ieFix.js' 6 | import { setAriaHidden } from './aria.js' 7 | import globalState from '../globalState.js' 8 | 9 | export const SHOW_CLASS_TIMEOUT = 10 10 | 11 | /** 12 | * Open popup, add necessary classes and styles, fix scrollbar 13 | * 14 | * @param params 15 | */ 16 | export const openPopup = (params) => { 17 | const container = dom.getContainer() 18 | const popup = dom.getPopup() 19 | 20 | if (typeof params.willOpen === 'function') { 21 | params.willOpen(popup) 22 | } else if (typeof params.onBeforeOpen === 'function') { 23 | params.onBeforeOpen(popup) // @deprecated 24 | } 25 | 26 | const bodyStyles = window.getComputedStyle(document.body) 27 | const initialBodyOverflow = bodyStyles.overflowY 28 | addClasses(container, popup, params) 29 | 30 | // scrolling is 'hidden' until animation is done, after that 'auto' 31 | setTimeout(() => { 32 | setScrollingVisibility(container, popup) 33 | }, SHOW_CLASS_TIMEOUT) 34 | 35 | if (dom.isModal()) { 36 | fixScrollContainer(container, params.scrollbarPadding, initialBodyOverflow) 37 | setAriaHidden() 38 | } 39 | 40 | if (!dom.isToast() && !globalState.previousActiveElement) { 41 | globalState.previousActiveElement = document.activeElement 42 | } 43 | 44 | runDidOpen(popup, params) 45 | 46 | dom.removeClass(container, swalClasses['no-transition']) 47 | } 48 | 49 | const runDidOpen = (popup, params) => { 50 | if (typeof params.didOpen === 'function') { 51 | setTimeout(() => params.didOpen(popup)) 52 | } else if (typeof params.onOpen === 'function') { 53 | setTimeout(() => params.onOpen(popup)) // @deprecated 54 | } 55 | } 56 | 57 | const swalOpenAnimationFinished = (event) => { 58 | const popup = dom.getPopup() 59 | if (event.target !== popup) { 60 | return 61 | } 62 | const container = dom.getContainer() 63 | popup.removeEventListener(dom.animationEndEvent, swalOpenAnimationFinished) 64 | container.style.overflowY = 'auto' 65 | } 66 | 67 | const setScrollingVisibility = (container, popup) => { 68 | if (dom.animationEndEvent && dom.hasCssAnimation(popup)) { 69 | container.style.overflowY = 'hidden' 70 | popup.addEventListener(dom.animationEndEvent, swalOpenAnimationFinished) 71 | } else { 72 | container.style.overflowY = 'auto' 73 | } 74 | } 75 | 76 | const fixScrollContainer = (container, scrollbarPadding, initialBodyOverflow) => { 77 | iOSfix() 78 | IEfix() 79 | 80 | if (scrollbarPadding && initialBodyOverflow !== 'hidden') { 81 | fixScrollbar() 82 | } 83 | 84 | // sweetalert2/issues/1247 85 | setTimeout(() => { 86 | container.scrollTop = 0 87 | }) 88 | } 89 | 90 | const addClasses = (container, popup, params) => { 91 | dom.addClass(container, params.showClass.backdrop) 92 | // the workaround with setting/unsetting opacity is needed for #2019 and 2059 93 | popup.style.setProperty('opacity', '0', 'important') 94 | dom.show(popup) 95 | setTimeout(() => { 96 | // Animate popup right after showing it 97 | dom.addClass(popup, params.showClass.popup) 98 | // and remove the opacity workaround 99 | popup.style.removeProperty('opacity') 100 | }, SHOW_CLASS_TIMEOUT) // 10ms in order to fix #2062 101 | 102 | dom.addClass([document.documentElement, document.body], swalClasses.shown) 103 | if (params.heightAuto && params.backdrop && !params.toast) { 104 | dom.addClass([document.documentElement, document.body], swalClasses['height-auto']) 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/utils/scrollbarFix.js: -------------------------------------------------------------------------------- 1 | import * as dom from './dom/index.js' 2 | 3 | export const fixScrollbar = () => { 4 | // for queues, do not do this more than once 5 | if (dom.states.previousBodyPadding !== null) { 6 | return 7 | } 8 | // if the body has overflow 9 | if (document.body.scrollHeight > window.innerHeight) { 10 | // add padding so the content doesn't shift after removal of scrollbar 11 | dom.states.previousBodyPadding = parseInt(window.getComputedStyle(document.body).getPropertyValue('padding-right')) 12 | document.body.style.paddingRight = `${dom.states.previousBodyPadding + dom.measureScrollbar()}px` 13 | } 14 | } 15 | 16 | export const undoScrollbar = () => { 17 | if (dom.states.previousBodyPadding !== null) { 18 | document.body.style.paddingRight = `${dom.states.previousBodyPadding}px` 19 | dom.states.previousBodyPadding = null 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/utils/setParameters.js: -------------------------------------------------------------------------------- 1 | import { warn, callIfFunction } from './utils.js' 2 | import * as dom from './dom/index.js' 3 | import defaultInputValidators from './defaultInputValidators.js' 4 | 5 | function setDefaultInputValidators (params) { 6 | // Use default `inputValidator` for supported input types if not provided 7 | if (!params.inputValidator) { 8 | Object.keys(defaultInputValidators).forEach((key) => { 9 | if (params.input === key) { 10 | params.inputValidator = defaultInputValidators[key] 11 | } 12 | }) 13 | } 14 | } 15 | 16 | function validateCustomTargetElement (params) { 17 | // Determine if the custom target element is valid 18 | if ( 19 | !params.target || 20 | (typeof params.target === 'string' && !document.querySelector(params.target)) || 21 | (typeof params.target !== 'string' && !params.target.appendChild) 22 | ) { 23 | warn('Target parameter is not valid, defaulting to "body"') 24 | params.target = 'body' 25 | } 26 | } 27 | 28 | /** 29 | * Set type, text and actions on popup 30 | * 31 | * @param params 32 | * @returns {boolean} 33 | */ 34 | export default function setParameters (params) { 35 | setDefaultInputValidators(params) 36 | 37 | // showLoaderOnConfirm && preConfirm 38 | if (params.showLoaderOnConfirm && !params.preConfirm) { 39 | warn( 40 | 'showLoaderOnConfirm is set to true, but preConfirm is not defined.\n' + 41 | 'showLoaderOnConfirm should be used together with preConfirm, see usage example:\n' + 42 | 'https://sweetalert2.github.io/#ajax-request' 43 | ) 44 | } 45 | 46 | // params.animation will be actually used in renderPopup.js 47 | // but in case when params.animation is a function, we need to call that function 48 | // before popup (re)initialization, so it'll be possible to check Swal.isVisible() 49 | // inside the params.animation function 50 | params.animation = callIfFunction(params.animation) 51 | 52 | validateCustomTargetElement(params) 53 | 54 | // Replace newlines with
in title 55 | if (typeof params.title === 'string') { 56 | params.title = params.title.split('\n').join('
') 57 | } 58 | 59 | dom.init(params) 60 | } 61 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/utils/utils.js: -------------------------------------------------------------------------------- 1 | export const consolePrefix = 'SweetAlert2:' 2 | 3 | /** 4 | * Filter the unique values into a new array 5 | * @param arr 6 | */ 7 | export const uniqueArray = (arr) => { 8 | const result = [] 9 | for (let i = 0; i < arr.length; i++) { 10 | if (result.indexOf(arr[i]) === -1) { 11 | result.push(arr[i]) 12 | } 13 | } 14 | return result 15 | } 16 | 17 | /** 18 | * Capitalize the first letter of a string 19 | * @param str 20 | */ 21 | export const capitalizeFirstLetter = (str) => str.charAt(0).toUpperCase() + str.slice(1) 22 | 23 | /** 24 | * Returns the array of object values (Object.values isn't supported in IE11) 25 | * @param obj 26 | */ 27 | export const objectValues = (obj) => Object.keys(obj).map(key => obj[key]) 28 | 29 | /** 30 | * Convert NodeList to Array 31 | * @param nodeList 32 | */ 33 | export const toArray = (nodeList) => Array.prototype.slice.call(nodeList) 34 | 35 | /** 36 | * Standardise console warnings 37 | * @param message 38 | */ 39 | export const warn = (message) => { 40 | console.warn(`${consolePrefix} ${message}`) 41 | } 42 | 43 | /** 44 | * Standardise console errors 45 | * @param message 46 | */ 47 | export const error = (message) => { 48 | console.error(`${consolePrefix} ${message}`) 49 | } 50 | 51 | /** 52 | * Private global state for `warnOnce` 53 | * @type {Array} 54 | * @private 55 | */ 56 | const previousWarnOnceMessages = [] 57 | 58 | /** 59 | * Show a console warning, but only if it hasn't already been shown 60 | * @param message 61 | */ 62 | export const warnOnce = (message) => { 63 | if (!previousWarnOnceMessages.includes(message)) { 64 | previousWarnOnceMessages.push(message) 65 | warn(message) 66 | } 67 | } 68 | 69 | /** 70 | * Show a one-time console warning about deprecated params/methods 71 | */ 72 | export const warnAboutDeprecation = (deprecatedParam, useInstead) => { 73 | warnOnce(`"${deprecatedParam}" is deprecated and will be removed in the next major release. Please use "${useInstead}" instead.`) 74 | } 75 | 76 | /** 77 | * If `arg` is a function, call it (with no arguments or context) and return the result. 78 | * Otherwise, just pass the value through 79 | * @param arg 80 | */ 81 | export const callIfFunction = (arg) => typeof arg === 'function' ? arg() : arg 82 | 83 | export const hasToPromiseFn = (arg) => arg && typeof arg.toPromise === 'function' 84 | 85 | export const asPromise = (arg) => hasToPromiseFn(arg) ? arg.toPromise() : Promise.resolve(arg) 86 | 87 | export const isPromise = (arg) => arg && Promise.resolve(arg) === arg 88 | -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/variables.css: -------------------------------------------------------------------------------- 1 | /* No CSS *//*# sourceMappingURL=variables.css.map */ -------------------------------------------------------------------------------- /public/assets/sweetalert2/src/variables.css.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "mappings": "", 4 | "sources": [ 5 | "variables.scss" 6 | ], 7 | "names": [], 8 | "file": "variables.css" 9 | } -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eripratama1/gis-laravel-leaflet/378973290dba70decde46fba8e3b5883d2cd237d/public/favicon.ico -------------------------------------------------------------------------------- /public/index.php: -------------------------------------------------------------------------------- 1 | make(Kernel::class); 50 | 51 | $response = $kernel->handle( 52 | $request = Request::capture() 53 | )->send(); 54 | 55 | $kernel->terminate($request, $response); 56 | -------------------------------------------------------------------------------- /public/mix-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "/js/app.js": "/js/app.js", 3 | "/css/app.css": "/css/app.css" 4 | } 5 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /resources/css/app.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eripratama1/gis-laravel-leaflet/378973290dba70decde46fba8e3b5883d2cd237d/resources/css/app.css -------------------------------------------------------------------------------- /resources/js/app.js: -------------------------------------------------------------------------------- 1 | require('./bootstrap'); 2 | -------------------------------------------------------------------------------- /resources/js/bootstrap.js: -------------------------------------------------------------------------------- 1 | window._ = require('lodash'); 2 | 3 | try { 4 | require('bootstrap'); 5 | } catch (e) {} 6 | 7 | /** 8 | * We'll load the axios HTTP library which allows us to easily issue requests 9 | * to our Laravel back-end. This library automatically handles sending the 10 | * CSRF token as a header based on the value of the "XSRF" token cookie. 11 | */ 12 | 13 | window.axios = require('axios'); 14 | 15 | window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; 16 | 17 | /** 18 | * Echo exposes an expressive API for subscribing to channels and listening 19 | * for events that are broadcast by Laravel. Echo and event broadcasting 20 | * allows your team to easily build robust real-time web applications. 21 | */ 22 | 23 | // import Echo from 'laravel-echo'; 24 | 25 | // window.Pusher = require('pusher-js'); 26 | 27 | // window.Echo = new Echo({ 28 | // broadcaster: 'pusher', 29 | // key: process.env.MIX_PUSHER_APP_KEY, 30 | // cluster: process.env.MIX_PUSHER_APP_CLUSTER, 31 | // forceTLS: true 32 | // }); 33 | -------------------------------------------------------------------------------- /resources/sass/_variables.scss: -------------------------------------------------------------------------------- 1 | // Body 2 | $body-bg: #f8fafc; 3 | 4 | // Typography 5 | $font-family-sans-serif: 'Nunito', sans-serif; 6 | $font-size-base: 0.9rem; 7 | $line-height-base: 1.6; 8 | -------------------------------------------------------------------------------- /resources/sass/app.scss: -------------------------------------------------------------------------------- 1 | // Fonts 2 | @import url('https://fonts.googleapis.com/css?family=Nunito'); 3 | 4 | // Variables 5 | @import 'variables'; 6 | 7 | // Bootstrap 8 | @import '~bootstrap/scss/bootstrap'; 9 | -------------------------------------------------------------------------------- /resources/views/auth/login.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |
7 |
8 | 9 | ** Login menggunakan akun administrator
10 | ** Email (admin@email.test)
11 | ** Password (password123)
12 | ** Jika ingin menggunakan akun baru silahkan lakukan register 13 |
14 |
15 |
16 |
{{ __('Login') }}
17 | 18 |
19 |
20 | @csrf 21 | 22 |
23 | 24 | 25 |
26 | 27 | 28 | @error('email') 29 | 30 | {{ $message }} 31 | 32 | @enderror 33 |
34 |
35 | 36 |
37 | 38 | 39 |
40 | 41 | 42 | @error('password') 43 | 44 | {{ $message }} 45 | 46 | @enderror 47 |
48 |
49 | 50 |
51 |
52 |
53 | 54 | 55 | 58 |
59 |
60 |
61 | 62 |
63 |
64 | 67 | 68 | @if (Route::has('password.request')) 69 | 70 | {{ __('Forgot Your Password?') }} 71 | 72 | @endif 73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 | @endsection 82 | -------------------------------------------------------------------------------- /resources/views/auth/passwords/confirm.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |
7 |
8 |
{{ __('Confirm Password') }}
9 | 10 |
11 | {{ __('Please confirm your password before continuing.') }} 12 | 13 |
14 | @csrf 15 | 16 |
17 | 18 | 19 |
20 | 21 | 22 | @error('password') 23 | 24 | {{ $message }} 25 | 26 | @enderror 27 |
28 |
29 | 30 |
31 |
32 | 35 | 36 | @if (Route::has('password.request')) 37 | 38 | {{ __('Forgot Your Password?') }} 39 | 40 | @endif 41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | @endsection 50 | -------------------------------------------------------------------------------- /resources/views/auth/passwords/email.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |
7 |
8 |
{{ __('Reset Password') }}
9 | 10 |
11 | @if (session('status')) 12 | 15 | @endif 16 | 17 |
18 | @csrf 19 | 20 |
21 | 22 | 23 |
24 | 25 | 26 | @error('email') 27 | 28 | {{ $message }} 29 | 30 | @enderror 31 |
32 |
33 | 34 |
35 |
36 | 39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | @endsection 48 | -------------------------------------------------------------------------------- /resources/views/auth/passwords/reset.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |
7 |
8 |
{{ __('Reset Password') }}
9 | 10 |
11 |
12 | @csrf 13 | 14 | 15 | 16 |
17 | 18 | 19 |
20 | 21 | 22 | @error('email') 23 | 24 | {{ $message }} 25 | 26 | @enderror 27 |
28 |
29 | 30 |
31 | 32 | 33 |
34 | 35 | 36 | @error('password') 37 | 38 | {{ $message }} 39 | 40 | @enderror 41 |
42 |
43 | 44 |
45 | 46 | 47 |
48 | 49 |
50 |
51 | 52 |
53 |
54 | 57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 | @endsection 66 | -------------------------------------------------------------------------------- /resources/views/auth/register.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |
7 |
8 |
{{ __('Register') }}
9 | 10 |
11 |
12 | @csrf 13 | 14 |
15 | 16 | 17 |
18 | 19 | 20 | @error('name') 21 | 22 | {{ $message }} 23 | 24 | @enderror 25 |
26 |
27 | 28 |
29 | 30 | 31 |
32 | 33 | 34 | @error('email') 35 | 36 | {{ $message }} 37 | 38 | @enderror 39 |
40 |
41 | 42 |
43 | 44 | 45 |
46 | 47 | 48 | @error('password') 49 | 50 | {{ $message }} 51 | 52 | @enderror 53 |
54 |
55 | 56 |
57 | 58 | 59 |
60 | 61 |
62 |
63 | 64 |
65 |
66 | 69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | @endsection 78 | -------------------------------------------------------------------------------- /resources/views/auth/verify.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |
7 |
8 |
{{ __('Verify Your Email Address') }}
9 | 10 |
11 | @if (session('resent')) 12 | 15 | @endif 16 | 17 | {{ __('Before proceeding, please check your email for a verification link.') }} 18 | {{ __('If you did not receive the email') }}, 19 |
20 | @csrf 21 | . 22 |
23 |
24 |
25 |
26 |
27 |
28 | @endsection 29 | -------------------------------------------------------------------------------- /resources/views/centrepoint/action.blade.php: -------------------------------------------------------------------------------- 1 | {{-- pada view action terdapat 2 button edit data dan hapus data --}} 2 | Edit 3 | 4 | 5 | {{-- pada view action kita meload cdn sweetalert 2 untuk menampilkan alert dialog dari sweet alert2 --}} 6 | 7 | 8 | -------------------------------------------------------------------------------- /resources/views/centrepoint/index.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('style-css') 4 | {{-- load jquery datatable untuk menggunakannya --}} 5 | 6 | @endsection 7 | 8 | @section('content') 9 |
10 |
11 |
12 |
13 |
{{ __('Set Centre Point') }}
14 |
15 | Tambah Data 16 | 17 | @if (session('success')) 18 | 21 | @endif 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |
No.Titik KoordinatOpsi
33 | 34 | {{-- tag form di gunakan untuk melakukan hapus data centrepoint yang di pilih 35 | jadi ketika button yang ada pada view action.blade di klik akan menjalankan 36 | fungsi javascript sweet alert2 --}} 37 |
38 | @csrf 39 | @method("DELETE") 40 | 41 |
42 |
43 |
44 |
45 |
46 |
47 | @endsection 48 | 49 | @push('javascript') 50 | {{-- load jquery dan jquery datatable --}} 51 | 52 | 53 | 54 | 79 | @endpush 80 | -------------------------------------------------------------------------------- /resources/views/home.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |
7 |
8 |
{{ __('Dashboard') }}
9 | 10 |
11 | @if (session('status')) 12 | 15 | @endif 16 | 17 | {{ __('You are logged in!') }} 18 |
19 |
20 |
21 |
22 |
23 | @endsection 24 | -------------------------------------------------------------------------------- /resources/views/space/action.blade.php: -------------------------------------------------------------------------------- 1 | Edit 2 | 3 | 4 | 5 | 6 | {{-- isi dari file view action.space sama dengan file view action.centrepoint --}} 7 | 8 | -------------------------------------------------------------------------------- /resources/views/space/index.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('style-css') 4 | 5 | @endsection 6 | 7 | {{-- Untuk view index space ini hampir sama dengan view index centrepoint dimana kita memuat cdn datatable 8 | css dan js yang membedakannya ada pada ajax server side di bagian push('javascript') yaitu pada route 9 | 10 | --}} 11 | @section('content') 12 |
13 |
14 |
15 |
16 |
{{ __('Lists Space') }}
17 |
18 | Tambah Data 19 | 20 | @if (session('success')) 21 | 24 | @endif 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 |
No.Nama SpaceOpsi
36 |
37 | @csrf 38 | @method("DELETE") 39 | 40 |
41 |
42 |
43 |
44 |
45 |
46 | @endsection 47 | 48 | @push('javascript') 49 | 50 | 51 | 77 | @endpush 78 | -------------------------------------------------------------------------------- /routes/api.php: -------------------------------------------------------------------------------- 1 | get('/user', function (Request $request) { 18 | return $request->user(); 19 | }); 20 | -------------------------------------------------------------------------------- /routes/channels.php: -------------------------------------------------------------------------------- 1 | id === (int) $id; 18 | }); 19 | -------------------------------------------------------------------------------- /routes/console.php: -------------------------------------------------------------------------------- 1 | comment(Inspiring::quote()); 19 | })->purpose('Display an inspiring quote'); 20 | -------------------------------------------------------------------------------- /routes/web.php: -------------------------------------------------------------------------------- 1 | name('home'); 28 | Route::get('/map',[App\Http\Controllers\MapController::class,'index'])->name('map.index'); 29 | Route::get('/map/{slug}',[App\Http\Controllers\MapController::class,'show'])->name('map.show'); 30 | 31 | Route::resource('centre-point',(CentrePointController::class)); 32 | Route::resource('category',(CategoryController::class)); 33 | Route::resource('space',(SpaceController::class)); 34 | 35 | Route::get('/centrepoint/data',[DataController::class,'centrepoint'])->name('centre-point.data'); 36 | Route::get('/categories/data',[DataController::class,'categories'])->name('data-category'); 37 | Route::get('/spaces/data',[DataController::class,'spaces'])->name('data-space'); 38 | -------------------------------------------------------------------------------- /storage/app/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !public/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /storage/app/public/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/.gitignore: -------------------------------------------------------------------------------- 1 | compiled.php 2 | config.php 3 | down 4 | events.scanned.php 5 | maintenance.php 6 | routes.php 7 | routes.scanned.php 8 | schedule-* 9 | services.json 10 | -------------------------------------------------------------------------------- /storage/framework/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !data/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /storage/framework/cache/data/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/sessions/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/testing/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/views/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/logs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /tests/CreatesApplication.php: -------------------------------------------------------------------------------- 1 | make(Kernel::class)->bootstrap(); 19 | 20 | return $app; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/Feature/ExampleTest.php: -------------------------------------------------------------------------------- 1 | get('/'); 18 | 19 | $response->assertStatus(200); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tests/TestCase.php: -------------------------------------------------------------------------------- 1 | assertTrue(true); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /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 | .sourceMaps(); 17 | --------------------------------------------------------------------------------