From 300b53942d7600323045b2bec29c73e7efb51427 Mon Sep 17 00:00:00 2001 From: R Date: Thu, 15 Sep 2022 11:47:36 +0700 Subject: [PATCH] Add Login & Register --- Modules/Linksehat/Config/.gitkeep | 0 Modules/Linksehat/Config/config.php | 6 + Modules/Linksehat/Console/.gitkeep | 0 .../Linksehat/Database/Migrations/.gitkeep | 0 Modules/Linksehat/Database/Seeders/.gitkeep | 0 .../Seeders/LinksehatDatabaseSeeder.php | 21 +++ Modules/Linksehat/Database/factories/.gitkeep | 0 Modules/Linksehat/Entities/.gitkeep | 0 Modules/Linksehat/Http/Controllers/.gitkeep | 0 .../Http/Controllers/Api/AuthController.php | 131 ++++++++++++++++++ .../Http/Controllers/LinksehatController.php | 79 +++++++++++ Modules/Linksehat/Http/Middleware/.gitkeep | 0 Modules/Linksehat/Http/Requests/.gitkeep | 0 Modules/Linksehat/Providers/.gitkeep | 0 .../Providers/LinksehatServiceProvider.php | 112 +++++++++++++++ .../Providers/RouteServiceProvider.php | 69 +++++++++ Modules/Linksehat/Resources/assets/.gitkeep | 0 Modules/Linksehat/Resources/assets/js/app.js | 0 .../Linksehat/Resources/assets/sass/app.scss | 0 Modules/Linksehat/Resources/lang/.gitkeep | 0 Modules/Linksehat/Resources/views/.gitkeep | 0 .../Linksehat/Resources/views/index.blade.php | 9 ++ .../Resources/views/layouts/master.blade.php | 19 +++ Modules/Linksehat/Routes/.gitkeep | 0 Modules/Linksehat/Routes/api.php | 23 +++ Modules/Linksehat/Routes/web.php | 16 +++ Modules/Linksehat/Tests/Feature/.gitkeep | 0 Modules/Linksehat/Tests/Unit/.gitkeep | 0 Modules/Linksehat/composer.json | 23 +++ Modules/Linksehat/module.json | 13 ++ Modules/Linksehat/package.json | 21 +++ Modules/Linksehat/webpack.mix.js | 14 ++ app/Models/Address.php | 11 ++ app/Models/Organization.php | 9 ++ app/Models/User.php | 3 + .../2014_10_12_000000_create_users_table.php | 8 +- ...22_09_14_095154_create_addresses_table.php | 43 ++++++ .../src/components/hook-form/RHFSwitch.tsx | 27 ++++ .../dashboard/src/pages/Corporates/Form.tsx | 1 + modules_statuses.json | 3 +- 40 files changed, 658 insertions(+), 3 deletions(-) create mode 100644 Modules/Linksehat/Config/.gitkeep create mode 100644 Modules/Linksehat/Config/config.php create mode 100644 Modules/Linksehat/Console/.gitkeep create mode 100644 Modules/Linksehat/Database/Migrations/.gitkeep create mode 100644 Modules/Linksehat/Database/Seeders/.gitkeep create mode 100644 Modules/Linksehat/Database/Seeders/LinksehatDatabaseSeeder.php create mode 100644 Modules/Linksehat/Database/factories/.gitkeep create mode 100644 Modules/Linksehat/Entities/.gitkeep create mode 100644 Modules/Linksehat/Http/Controllers/.gitkeep create mode 100644 Modules/Linksehat/Http/Controllers/Api/AuthController.php create mode 100644 Modules/Linksehat/Http/Controllers/LinksehatController.php create mode 100644 Modules/Linksehat/Http/Middleware/.gitkeep create mode 100644 Modules/Linksehat/Http/Requests/.gitkeep create mode 100644 Modules/Linksehat/Providers/.gitkeep create mode 100644 Modules/Linksehat/Providers/LinksehatServiceProvider.php create mode 100644 Modules/Linksehat/Providers/RouteServiceProvider.php create mode 100644 Modules/Linksehat/Resources/assets/.gitkeep create mode 100644 Modules/Linksehat/Resources/assets/js/app.js create mode 100644 Modules/Linksehat/Resources/assets/sass/app.scss create mode 100644 Modules/Linksehat/Resources/lang/.gitkeep create mode 100644 Modules/Linksehat/Resources/views/.gitkeep create mode 100644 Modules/Linksehat/Resources/views/index.blade.php create mode 100644 Modules/Linksehat/Resources/views/layouts/master.blade.php create mode 100644 Modules/Linksehat/Routes/.gitkeep create mode 100644 Modules/Linksehat/Routes/api.php create mode 100644 Modules/Linksehat/Routes/web.php create mode 100644 Modules/Linksehat/Tests/Feature/.gitkeep create mode 100644 Modules/Linksehat/Tests/Unit/.gitkeep create mode 100644 Modules/Linksehat/composer.json create mode 100644 Modules/Linksehat/module.json create mode 100644 Modules/Linksehat/package.json create mode 100644 Modules/Linksehat/webpack.mix.js create mode 100644 app/Models/Address.php create mode 100644 database/migrations/2022_09_14_095154_create_addresses_table.php diff --git a/Modules/Linksehat/Config/.gitkeep b/Modules/Linksehat/Config/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Modules/Linksehat/Config/config.php b/Modules/Linksehat/Config/config.php new file mode 100644 index 00000000..a6ce97ac --- /dev/null +++ b/Modules/Linksehat/Config/config.php @@ -0,0 +1,6 @@ + 'Linksehat', + 'otp_valid_minutes' => 10 +]; diff --git a/Modules/Linksehat/Console/.gitkeep b/Modules/Linksehat/Console/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Modules/Linksehat/Database/Migrations/.gitkeep b/Modules/Linksehat/Database/Migrations/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Modules/Linksehat/Database/Seeders/.gitkeep b/Modules/Linksehat/Database/Seeders/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Modules/Linksehat/Database/Seeders/LinksehatDatabaseSeeder.php b/Modules/Linksehat/Database/Seeders/LinksehatDatabaseSeeder.php new file mode 100644 index 00000000..c940e344 --- /dev/null +++ b/Modules/Linksehat/Database/Seeders/LinksehatDatabaseSeeder.php @@ -0,0 +1,21 @@ +call("OthersTableSeeder"); + } +} diff --git a/Modules/Linksehat/Database/factories/.gitkeep b/Modules/Linksehat/Database/factories/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Modules/Linksehat/Entities/.gitkeep b/Modules/Linksehat/Entities/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Modules/Linksehat/Http/Controllers/.gitkeep b/Modules/Linksehat/Http/Controllers/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Modules/Linksehat/Http/Controllers/Api/AuthController.php b/Modules/Linksehat/Http/Controllers/Api/AuthController.php new file mode 100644 index 00000000..1f76add8 --- /dev/null +++ b/Modules/Linksehat/Http/Controllers/Api/AuthController.php @@ -0,0 +1,131 @@ +validate([ + 'phone' => 'required' + ]); + + $user = User::updateOrCreate([ + 'phone' => $request->phone + ], [ + 'phone' => $request->phone, + 'otp' => rand(1000, 9999), + 'otp_created_at' => now() + ]); + if (!$user) { + return response()->json([ + 'message' => "User dengan nomor telepon ".$request->phone." tidak ditemukan" + ], 404); + } + + return response()->json([ + 'message' => 'OTP Terkirim', + 'data' => [ + 'otp_valid_until' => $user->otp_created_at->addMinutes(config('linksehat.otp_valid_minutes')) + ] + ]); + } + + public function login(Request $request) + { + $request->validate([ + 'email' => 'email', + 'password' => 'required_with:email', + 'phone' => '', + 'otp' => 'required_with:phone', + ]); + + $loginType = null; + + if ($request->has('password') && !empty($request->password)) { + $user = User::query() + ->where('email', $request->email) + ->first(); + + $loginType = 'email'; + } + + if ($request->has('otp') && !empty($request->otp)) { + $user = User::query() + ->where('phone', $request->phone) + ->first(); + + $loginType = 'phone'; + } + + if (!$user) { + return response(['message' => 'User Tidak Ditemukan'], 404); + } + + if ($loginType == 'email') { + if (!Hash::check($request->password, $user->password)) { + return response(['message' => 'Password Salah'], 403); + } + } else if ($loginType == 'phone') { + if ($request->otp != $user->otp) { + return response(['message' => 'OTP Salah'], 403); + } + } else { + return response(['message' => 'Mode Login Tidak Dikenal'], 403); + } + + return response([ + 'message' => 'Selamat Datang', + 'user' => $user, + 'token' => $user->createToken('app')->plainTextToken + ]); + } + + public function register(Request $request) + { + $validator = Validator::make($request->all(), [ + 'email' => 'required|email|unique:users,email', + 'password' => [ + 'required', + 'confirmed', + 'min:8', + 'regex:/.*[0-9].*/', + 'regex:/.*[a-z].*/', + 'regex:/.*[A-Z].*/', + ] + ], [ + 'password.regex' => "Password harus minimal 8 karakter, kombinasi huruf besar kecil dan angka" + ])->validate(); + + try { + $user = User::create([ + 'email' => $request->email, + 'password' => Hash::make($request->password), + ]); + + return response()->json([ + 'message' => 'Akun berhasil dibuat, silahkan cek E-mail untuk konfirmasi' + ], 201); + } catch (\Exception $e) { + return response()->json([ + 'message' => 'Terjadi masalah ketika mendaftar', + 'error_message' => $e->getMessage() + ], 403); + } + } + + public function logout(Request $request) + { + $token = $request->bearerToken(); + Auth::user()->tokens()->where('id', $token)->delete(); + + return response(['message' => 'Berhasil Logout.']); + } +} diff --git a/Modules/Linksehat/Http/Controllers/LinksehatController.php b/Modules/Linksehat/Http/Controllers/LinksehatController.php new file mode 100644 index 00000000..0aae71ee --- /dev/null +++ b/Modules/Linksehat/Http/Controllers/LinksehatController.php @@ -0,0 +1,79 @@ +registerTranslations(); + $this->registerConfig(); + $this->registerViews(); + $this->loadMigrationsFrom(module_path($this->moduleName, 'Database/Migrations')); + } + + /** + * Register the service provider. + * + * @return void + */ + public function register() + { + $this->app->register(RouteServiceProvider::class); + } + + /** + * Register config. + * + * @return void + */ + protected function registerConfig() + { + $this->publishes([ + module_path($this->moduleName, 'Config/config.php') => config_path($this->moduleNameLower . '.php'), + ], 'config'); + $this->mergeConfigFrom( + module_path($this->moduleName, 'Config/config.php'), $this->moduleNameLower + ); + } + + /** + * Register views. + * + * @return void + */ + public function registerViews() + { + $viewPath = resource_path('views/modules/' . $this->moduleNameLower); + + $sourcePath = module_path($this->moduleName, 'Resources/views'); + + $this->publishes([ + $sourcePath => $viewPath + ], ['views', $this->moduleNameLower . '-module-views']); + + $this->loadViewsFrom(array_merge($this->getPublishableViewPaths(), [$sourcePath]), $this->moduleNameLower); + } + + /** + * Register translations. + * + * @return void + */ + public function registerTranslations() + { + $langPath = resource_path('lang/modules/' . $this->moduleNameLower); + + if (is_dir($langPath)) { + $this->loadTranslationsFrom($langPath, $this->moduleNameLower); + } else { + $this->loadTranslationsFrom(module_path($this->moduleName, 'Resources/lang'), $this->moduleNameLower); + } + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides() + { + return []; + } + + private function getPublishableViewPaths(): array + { + $paths = []; + foreach (\Config::get('view.paths') as $path) { + if (is_dir($path . '/modules/' . $this->moduleNameLower)) { + $paths[] = $path . '/modules/' . $this->moduleNameLower; + } + } + return $paths; + } +} diff --git a/Modules/Linksehat/Providers/RouteServiceProvider.php b/Modules/Linksehat/Providers/RouteServiceProvider.php new file mode 100644 index 00000000..5c7a5539 --- /dev/null +++ b/Modules/Linksehat/Providers/RouteServiceProvider.php @@ -0,0 +1,69 @@ +mapApiRoutes(); + + $this->mapWebRoutes(); + } + + /** + * Define the "web" routes for the application. + * + * These routes all receive session state, CSRF protection, etc. + * + * @return void + */ + protected function mapWebRoutes() + { + Route::middleware('web') + ->namespace($this->moduleNamespace) + ->group(module_path('Linksehat', '/Routes/web.php')); + } + + /** + * Define the "api" routes for the application. + * + * These routes are typically stateless. + * + * @return void + */ + protected function mapApiRoutes() + { + Route::prefix('api') + ->middleware('api') + ->namespace($this->moduleNamespace) + ->group(module_path('Linksehat', '/Routes/api.php')); + } +} diff --git a/Modules/Linksehat/Resources/assets/.gitkeep b/Modules/Linksehat/Resources/assets/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Modules/Linksehat/Resources/assets/js/app.js b/Modules/Linksehat/Resources/assets/js/app.js new file mode 100644 index 00000000..e69de29b diff --git a/Modules/Linksehat/Resources/assets/sass/app.scss b/Modules/Linksehat/Resources/assets/sass/app.scss new file mode 100644 index 00000000..e69de29b diff --git a/Modules/Linksehat/Resources/lang/.gitkeep b/Modules/Linksehat/Resources/lang/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Modules/Linksehat/Resources/views/.gitkeep b/Modules/Linksehat/Resources/views/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Modules/Linksehat/Resources/views/index.blade.php b/Modules/Linksehat/Resources/views/index.blade.php new file mode 100644 index 00000000..66c6143e --- /dev/null +++ b/Modules/Linksehat/Resources/views/index.blade.php @@ -0,0 +1,9 @@ +@extends('linksehat::layouts.master') + +@section('content') +

Hello World

+ +

+ This view is loaded from module: {!! config('linksehat.name') !!} +

+@endsection diff --git a/Modules/Linksehat/Resources/views/layouts/master.blade.php b/Modules/Linksehat/Resources/views/layouts/master.blade.php new file mode 100644 index 00000000..52e851bb --- /dev/null +++ b/Modules/Linksehat/Resources/views/layouts/master.blade.php @@ -0,0 +1,19 @@ + + + + + + + Module Linksehat + + {{-- Laravel Mix - CSS File --}} + {{-- --}} + + + + @yield('content') + + {{-- Laravel Mix - JS File --}} + {{-- --}} + + diff --git a/Modules/Linksehat/Routes/.gitkeep b/Modules/Linksehat/Routes/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Modules/Linksehat/Routes/api.php b/Modules/Linksehat/Routes/api.php new file mode 100644 index 00000000..10107af7 --- /dev/null +++ b/Modules/Linksehat/Routes/api.php @@ -0,0 +1,23 @@ +get('/linksehat', function (Request $request) { + return $request->user(); +}); \ No newline at end of file diff --git a/Modules/Linksehat/Routes/web.php b/Modules/Linksehat/Routes/web.php new file mode 100644 index 00000000..87026d92 --- /dev/null +++ b/Modules/Linksehat/Routes/web.php @@ -0,0 +1,16 @@ +group(function() { + Route::get('/', 'LinksehatController@index'); +}); diff --git a/Modules/Linksehat/Tests/Feature/.gitkeep b/Modules/Linksehat/Tests/Feature/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Modules/Linksehat/Tests/Unit/.gitkeep b/Modules/Linksehat/Tests/Unit/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Modules/Linksehat/composer.json b/Modules/Linksehat/composer.json new file mode 100644 index 00000000..8d176452 --- /dev/null +++ b/Modules/Linksehat/composer.json @@ -0,0 +1,23 @@ +{ + "name": "nwidart/linksehat", + "description": "", + "authors": [ + { + "name": "Nicolas Widart", + "email": "n.widart@gmail.com" + } + ], + "extra": { + "laravel": { + "providers": [], + "aliases": { + + } + } + }, + "autoload": { + "psr-4": { + "Modules\\Linksehat\\": "" + } + } +} diff --git a/Modules/Linksehat/module.json b/Modules/Linksehat/module.json new file mode 100644 index 00000000..fae5c9b9 --- /dev/null +++ b/Modules/Linksehat/module.json @@ -0,0 +1,13 @@ +{ + "name": "Linksehat", + "alias": "linksehat", + "description": "", + "keywords": [], + "priority": 0, + "providers": [ + "Modules\\Linksehat\\Providers\\LinksehatServiceProvider" + ], + "aliases": {}, + "files": [], + "requires": [] +} diff --git a/Modules/Linksehat/package.json b/Modules/Linksehat/package.json new file mode 100644 index 00000000..73031461 --- /dev/null +++ b/Modules/Linksehat/package.json @@ -0,0 +1,21 @@ +{ + "private": true, + "scripts": { + "dev": "npm run development", + "development": "mix", + "watch": "mix watch", + "watch-poll": "mix watch -- --watch-options-poll=1000", + "hot": "mix watch --hot", + "prod": "npm run production", + "production": "mix --production" + }, + "devDependencies": { + "axios": "^0.21.4", + "dotenv": "^10.0.0", + "dotenv-expand": "^5.1.0", + "laravel-mix": "^6.0.31", + "laravel-mix-merge-manifest": "^2.0.0", + "lodash": "^4.17.21", + "postcss": "^8.3.7" + } +} diff --git a/Modules/Linksehat/webpack.mix.js b/Modules/Linksehat/webpack.mix.js new file mode 100644 index 00000000..87b2e362 --- /dev/null +++ b/Modules/Linksehat/webpack.mix.js @@ -0,0 +1,14 @@ +const dotenvExpand = require('dotenv-expand'); +dotenvExpand(require('dotenv').config({ path: '../../.env'/*, debug: true*/})); + +const mix = require('laravel-mix'); +require('laravel-mix-merge-manifest'); + +mix.setPublicPath('../../public').mergeManifest(); + +mix.js(__dirname + '/Resources/assets/js/app.js', 'js/linksehat.js') + .sass( __dirname + '/Resources/assets/sass/app.scss', 'css/linksehat.css'); + +if (mix.inProduction()) { + mix.version(); +} diff --git a/app/Models/Address.php b/app/Models/Address.php new file mode 100644 index 00000000..14f53910 --- /dev/null +++ b/app/Models/Address.php @@ -0,0 +1,11 @@ +belongsTo(Organization::class, 'part_of', 'id'); + } } diff --git a/app/Models/User.php b/app/Models/User.php index 281e04a5..e9aa9bb4 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -21,6 +21,9 @@ class User extends Authenticatable 'name', 'email', 'password', + 'phone', + 'otp', + 'otp_created_at' ]; /** diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2014_10_12_000000_create_users_table.php index 4663617b..a58ae68c 100644 --- a/database/migrations/2014_10_12_000000_create_users_table.php +++ b/database/migrations/2014_10_12_000000_create_users_table.php @@ -16,9 +16,13 @@ return new class extends Migration Schema::create('users', function (Blueprint $table) { $table->id(); // $table->string('name'); - $table->string('email')->unique(); + $table->string('email')->unique()->nullable(); $table->timestamp('email_verified_at')->nullable(); - $table->string('password'); + $table->string('password')->nullable(); + $table->string('phone')->unique()->nullable(); + $table->timestamp('phone_verified_at')->nullable(); + $table->string('otp', 10)->nullable(); + $table->timestamp('otp_created_at')->nullable(); $table->rememberToken(); $table->timestamps(); }); diff --git a/database/migrations/2022_09_14_095154_create_addresses_table.php b/database/migrations/2022_09_14_095154_create_addresses_table.php new file mode 100644 index 00000000..7d258d15 --- /dev/null +++ b/database/migrations/2022_09_14_095154_create_addresses_table.php @@ -0,0 +1,43 @@ +id(); + $table->morphs('addressable'); + $table->string('use')->nullable(); + $table->string('type')->nullable(); + $table->text('text')->nullable(); + $table->text('line')->nullable(); + $table->foreignId('province_id')->nullable(); + $table->foreignId('city_id')->nullable(); + $table->foreignId('district_id')->nullable(); + $table->foreignId('village_id')->nullable(); + $table->string('postal_code')->nullable(); + $table->string('rt')->nullable(); + $table->string('rw')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('addresses'); + } +}; diff --git a/frontend/dashboard/src/components/hook-form/RHFSwitch.tsx b/frontend/dashboard/src/components/hook-form/RHFSwitch.tsx index a56c548a..c1919aa1 100644 --- a/frontend/dashboard/src/components/hook-form/RHFSwitch.tsx +++ b/frontend/dashboard/src/components/hook-form/RHFSwitch.tsx @@ -2,6 +2,7 @@ import { useFormContext, Controller } from 'react-hook-form'; // @mui import { Switch, FormControlLabel, FormControlLabelProps } from '@mui/material'; +import { useEffect, useState } from 'react'; // ---------------------------------------------------------------------- @@ -27,3 +28,29 @@ export default function RHFSwitch({ name, ...other }: Props) { /> ); } + +// interface Props extends IProps { +// valueTrue: any, +// valueFalse: any, +// } + +// export function RHFSwitchEnum({ name, valueTrue, valueFalse, ...other}: Props) { +// const { control } = useFormContext(); +// const [isChecked, setIsChecked] = useState(valueTrue === field.value); +// useEffect(() => { +// // setIsChecked() +// }, []) + +// return ( +// } +// /> +// } +// {...other} +// /> +// ); +// } \ No newline at end of file diff --git a/frontend/dashboard/src/pages/Corporates/Form.tsx b/frontend/dashboard/src/pages/Corporates/Form.tsx index 22fcb97b..fb275df6 100644 --- a/frontend/dashboard/src/pages/Corporates/Form.tsx +++ b/frontend/dashboard/src/pages/Corporates/Form.tsx @@ -325,6 +325,7 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) { + { JSON.stringify(values.active) } Company Logo diff --git a/modules_statuses.json b/modules_statuses.json index a2cd3b49..b9809f6d 100644 --- a/modules_statuses.json +++ b/modules_statuses.json @@ -1,4 +1,5 @@ { "Internal": true, - "Client": true + "Client": true, + "Linksehat": true } \ No newline at end of file