├── public ├── favicon.ico ├── robots.txt ├── css │ ├── darkMode.css │ ├── lightmode.css │ ├── emailCard.css │ └── DarkToggleStyle.css ├── assets │ └── gifs │ │ ├── logo.jpg │ │ ├── user.png │ │ ├── admin.png │ │ ├── DarkMode .gif │ │ ├── LightMode.gif │ │ ├── paradrop.png │ │ ├── emailImage.png │ │ └── cancel_order.png ├── docs │ └── images │ │ └── navbar.png ├── .htaccess ├── js │ └── darkmode.js └── index.php ├── resources ├── css │ └── app.css ├── js │ ├── app.js │ └── bootstrap.js ├── views │ ├── dashboard │ │ ├── admin │ │ │ ├── statistics.blade.php │ │ │ └── profile.blade.php │ │ ├── index.blade.php │ │ ├── medicine │ │ │ ├── create.blade.php │ │ │ └── edit.blade.php │ │ ├── area │ │ │ ├── create.blade.php │ │ │ └── edit.blade.php │ │ ├── revenue │ │ │ └── index.blade.php │ │ └── order │ │ │ └── medicinesOrder.blade.php │ ├── vendor │ │ └── scribe │ │ │ ├── components │ │ │ └── badges │ │ │ │ ├── base.blade.php │ │ │ │ ├── auth.blade.php │ │ │ │ └── http-method.blade.php │ │ │ ├── markdown │ │ │ ├── auth.blade.php │ │ │ └── intro.blade.php │ │ │ ├── themes │ │ │ ├── default │ │ │ │ └── groups.blade.php │ │ │ └── elements │ │ │ │ ├── groups.blade.php │ │ │ │ └── components │ │ │ │ └── nested-fields.blade.php │ │ │ └── partials │ │ │ └── example-requests │ │ │ ├── bash.md.blade.php │ │ │ ├── python.md.blade.php │ │ │ ├── php.md.blade.php │ │ │ └── javascript.md.blade.php │ ├── emails │ │ ├── welcome.blade.php │ │ ├── inactiveClient.blade.php │ │ └── confirmOrder.blade.php │ ├── components │ │ └── modal.blade.php │ ├── auth │ │ ├── verify.blade.php │ │ └── passwords │ │ │ └── confirm.blade.php │ ├── welcome.blade.php │ └── confirmOrder │ │ ├── confirmed.blade.php │ │ └── canceledOrder.blade.php └── sass │ ├── _variables.scss │ └── app.scss ├── database ├── .gitignore ├── seeders │ ├── AdminSeeder.php │ ├── DatabaseSeeder.php │ ├── AreaSeeder.php │ ├── MedicineSeeder.php │ └── CountriesSeeder.php ├── migrations │ ├── 2023_03_27_233844_add_is_admin_to_users_table.php │ ├── 2023_03_31_223942_add_soft_delete_to_orders_table.php │ ├── 2023_04_01_131515_drop_avatar_image_column_from_pharmacies_table.php │ ├── 2023_04_01_132459_drop_avatar_image_column_from_clients_table.php │ ├── 2023_04_01_132718_drop_avatar_image_column_from_doctors_table.php │ ├── 2023_03_29_205736_add_nullable_to_userable_column_to_users_table.php │ ├── 2023_03_30_010421_add_soft_delete_to_medicines_table.php │ ├── 2023_04_03_072638_add_priority_to_pharmacies_table.php │ ├── 2023_03_30_001510_add_quantity_to__medicines_table.php │ ├── 2023_04_01_141328_remove_quantity_from_medicines.php │ ├── 2023_04_04_102839_add_country_id_to_areas_table.php │ ├── 2023_03_29_151018_add_usearable_column_to_users_table.php │ ├── 2023_03_28_144906_add_banned_at_column_to_doctors_table.php │ ├── 2023_03_30_103421_add_verified_at_to_clients_table.php │ ├── 2023_04_01_140736_remove_quantity_from_order_medicines.php │ ├── 2023_04_01_141243_add_quantity_to_order_medicines_tableta.php │ ├── 2023_03_29_205625_drop_morphs_from_users_table.php │ ├── 2023_04_01_140832_add_medicine_name_to_order_medicines_table.php │ ├── 2023_04_01_141116_modify_order_medicines_table.php │ ├── 2014_10_12_100000_create_password_reset_tokens_table.php │ ├── 2023_04_02_185343_modify_orders_table.php │ ├── 2023_03_29_234713_create_medicines_table.php │ ├── 2023_03_31_015313_create_order_prescription_table.php │ ├── 2023_03_26_184957_create_areas_table.php │ ├── 2014_10_12_100000_create_password_resets_table.php │ ├── 2023_03_31_015709_create_order_medicines_table.php │ ├── 2023_03_31_005432_add_creator_type_to_orders_table.php │ ├── 2019_08_19_000000_create_failed_jobs_table.php │ ├── 2023_03_31_002808_create_orders_table.php │ ├── 2014_10_12_000000_create_users_table.php │ ├── 2019_12_14_000001_create_personal_access_tokens_table.php │ ├── 2023_03_26_185023_create_pharmacies_table.php │ ├── 2023_04_01_124824_create_media_table.php │ ├── 2023_03_28_080759_create_doctors_table.php │ ├── 2023_03_29_173324_create_clients_table.php │ ├── 2023_03_29_201635_create_addresses_table.php │ ├── 2017_03_04_000000_create_bans_table.php │ ├── 2023_04_03_153548_setup_countries_table.php │ └── 2023_04_03_153549_charify_countries_table.php └── factories │ └── UserFactory.php ├── bootstrap ├── cache │ └── .gitignore └── app.php ├── storage ├── logs │ └── .gitignore ├── app │ ├── public │ │ └── .gitignore │ └── .gitignore └── framework │ ├── testing │ └── .gitignore │ ├── views │ └── .gitignore │ ├── cache │ ├── data │ │ └── .gitignore │ └── .gitignore │ ├── sessions │ └── .gitignore │ └── .gitignore ├── Procfile ├── .scribe ├── auth.md ├── .filehashes ├── intro.md ├── endpoints │ ├── 04.yaml │ └── custom.0.yaml └── endpoints.cache │ └── 04.yaml ├── tests ├── TestCase.php ├── Unit │ └── ExampleTest.php ├── Feature │ └── ExampleTest.php └── CreatesApplication.php ├── .gitattributes ├── stubs ├── export.query.stub ├── export.plain.stub ├── import.collection.stub ├── export.model.stub ├── export.query-model.stub └── import.model.stub ├── .gitignore ├── app ├── Models │ ├── Country.php │ ├── OrderPrescription.php │ ├── OrderMedicine.php │ ├── Area.php │ ├── Address.php │ ├── Medicine.php │ ├── Order.php │ ├── Doctor.php │ ├── User.php │ ├── Pharmacy.php │ └── Client.php ├── Http │ ├── Controllers │ │ ├── Controller.php │ │ ├── AdminController.php │ │ ├── HomeController.php │ │ ├── Auth │ │ │ ├── ForgotPasswordController.php │ │ │ ├── ResetPasswordController.php │ │ │ ├── LoginController.php │ │ │ ├── ConfirmPasswordController.php │ │ │ ├── VerificationController.php │ │ │ └── RegisterController.php │ │ ├── StripeController.php │ │ ├── OrderConfirmationController.php │ │ ├── RevenueController.php │ │ ├── ClientController.php │ │ └── ChartController.php │ ├── Middleware │ │ ├── EncryptCookies.php │ │ ├── VerifyCsrfToken.php │ │ ├── PreventRequestsDuringMaintenance.php │ │ ├── TrimStrings.php │ │ ├── TrustHosts.php │ │ ├── Authenticate.php │ │ ├── ValidateSignature.php │ │ ├── TrustProxies.php │ │ └── RedirectIfAuthenticated.php │ ├── Resources │ │ ├── MedicineResource.php │ │ ├── ClientResource.php │ │ ├── MedicineOrderResource.php │ │ ├── AddressResource.php │ │ └── OrderResource.php │ └── Requests │ │ ├── UpdateMedicineRequest.php │ │ ├── StoreAreaRequest.php │ │ ├── StoreMedicineRequest.php │ │ ├── UpdateAreaRequest.php │ │ ├── Api │ │ ├── CreateOrderRequest.php │ │ ├── ClientRegisterRequest.php │ │ ├── ClientUpdateProfileRequest.php │ │ └── AddressRegisterRequest.php │ │ ├── StoreDoctorRequest.php │ │ ├── StorePharmacyRequest.php │ │ ├── StoreAddressRequest.php │ │ ├── UpdateAddressRequest.php │ │ ├── UpdateDoctorRequest.php │ │ └── UpdatePharmacyRequest.php ├── Providers │ ├── BroadcastServiceProvider.php │ ├── AppServiceProvider.php │ ├── AuthServiceProvider.php │ ├── EventServiceProvider.php │ └── RouteServiceProvider.php ├── View │ └── Components │ │ └── Modal.php ├── Notifications │ └── ClientVerified.php ├── Console │ ├── Commands │ │ ├── UnbanUserCommand.php │ │ ├── NotifyInactiveClients.php │ │ ├── CreateAdminCommand.php │ │ └── ScanNewOrders.php │ └── Kernel.php ├── Exceptions │ └── Handler.php └── Mail │ ├── ConfirmOrder.php │ ├── InactiveClientMail.php │ └── WelcomeMail.php ├── .editorconfig ├── vite.config.js ├── package.json ├── routes ├── channels.php └── console.php ├── config ├── cors.php ├── services.php ├── view.php ├── hashing.php ├── broadcasting.php └── sanctum.php ├── phpunit.xml ├── .env.example ├── artisan └── composer.json /public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/css/app.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /database/.gitignore: -------------------------------------------------------------------------------- 1 | *.sqlite* 2 | -------------------------------------------------------------------------------- /bootstrap/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/logs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /storage/app/public/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web:vendor/bin/heroku-php-apache2 public/ 2 | -------------------------------------------------------------------------------- /storage/app/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !public/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /storage/framework/testing/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/views/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/cache/data/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/sessions/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !data/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /.scribe/auth.md: -------------------------------------------------------------------------------- 1 | # Authenticating requests 2 | 3 | This API is not authenticated. 4 | -------------------------------------------------------------------------------- /resources/js/app.js: -------------------------------------------------------------------------------- 1 | import "./bootstrap"; 2 | import Chart from "chart.js/auto"; 3 | -------------------------------------------------------------------------------- /public/css/darkMode.css: -------------------------------------------------------------------------------- 1 | 2 | .darkMode .tfoot { 3 | background-color: black !important; 4 | } 5 | -------------------------------------------------------------------------------- /public/assets/gifs/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DrugRadar/Pharmacy-Proj/HEAD/public/assets/gifs/logo.jpg -------------------------------------------------------------------------------- /public/assets/gifs/user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DrugRadar/Pharmacy-Proj/HEAD/public/assets/gifs/user.png -------------------------------------------------------------------------------- /public/assets/gifs/admin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DrugRadar/Pharmacy-Proj/HEAD/public/assets/gifs/admin.png -------------------------------------------------------------------------------- /public/docs/images/navbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DrugRadar/Pharmacy-Proj/HEAD/public/docs/images/navbar.png -------------------------------------------------------------------------------- /public/assets/gifs/DarkMode .gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DrugRadar/Pharmacy-Proj/HEAD/public/assets/gifs/DarkMode .gif -------------------------------------------------------------------------------- /public/assets/gifs/LightMode.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DrugRadar/Pharmacy-Proj/HEAD/public/assets/gifs/LightMode.gif -------------------------------------------------------------------------------- /public/assets/gifs/paradrop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DrugRadar/Pharmacy-Proj/HEAD/public/assets/gifs/paradrop.png -------------------------------------------------------------------------------- /resources/views/dashboard/admin/statistics.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | @section('content') 3 | 4 | @endsection -------------------------------------------------------------------------------- /public/assets/gifs/emailImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DrugRadar/Pharmacy-Proj/HEAD/public/assets/gifs/emailImage.png -------------------------------------------------------------------------------- /resources/views/dashboard/index.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | @section('content') 3 |
4 |
5 | @endsection -------------------------------------------------------------------------------- /resources/views/vendor/scribe/components/badges/base.blade.php: -------------------------------------------------------------------------------- 1 | {{ $text }} 2 | -------------------------------------------------------------------------------- /public/assets/gifs/cancel_order.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DrugRadar/Pharmacy-Proj/HEAD/public/assets/gifs/cancel_order.png -------------------------------------------------------------------------------- /public/css/lightmode.css: -------------------------------------------------------------------------------- 1 | .lightMode{ 2 | background-image: linear-gradient(330.93deg, #ffb13471 -6.5%, rgba(141, 41, 19, 0.322) 42.31%, transparent 81.62%) !important; 3 | } 4 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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.bunny.net/css?family=Nunito'); 3 | 4 | // Variables 5 | @import 'variables'; 6 | 7 | // Bootstrap 8 | @import 'bootstrap/scss/bootstrap'; 9 | -------------------------------------------------------------------------------- /resources/views/vendor/scribe/components/badges/auth.blade.php: -------------------------------------------------------------------------------- 1 | @if($authenticated)@component('scribe::components.badges.base', ['colour' => "darkred", 'text' => 'requires authentication']) 2 | @endcomponent 3 | @endif 4 | -------------------------------------------------------------------------------- /tests/TestCase.php: -------------------------------------------------------------------------------- 1 | 6 | Base URL: {!! $baseUrl !!} 7 | 8 | 9 | {!! $introText !!} 10 | 11 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 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 | .styleci.yml export-ignore 12 | -------------------------------------------------------------------------------- /.scribe/.filehashes: -------------------------------------------------------------------------------- 1 | # GENERATED. YOU SHOULDN'T MODIFY OR DELETE THIS FILE. 2 | # Scribe uses this file to know when you change something manually in your docs. 3 | .scribe/intro.md=108c50a021adf031b859f304eba64ddd 4 | .scribe/auth.md=9bee2b1ef8a238b2e58613fa636d5f39 -------------------------------------------------------------------------------- /resources/views/vendor/scribe/components/badges/http-method.blade.php: -------------------------------------------------------------------------------- 1 | @component('scribe::components.badges.base', [ 2 | 'colour' => \Knuckles\Scribe\Tools\WritingUtils::$httpMethodToCssColour[$method], 3 | 'text' => $method, 4 | ]) 5 | @endcomponent 6 | -------------------------------------------------------------------------------- /resources/views/emails/welcome.blade.php: -------------------------------------------------------------------------------- 1 | 2 | # Welcome User 3 | 4 | The body of your message. 5 | 6 | 7 | Button Text 8 | 9 | 10 | Thanks,
11 | {{ config('app.name') }} 12 |
13 | -------------------------------------------------------------------------------- /stubs/export.query.stub: -------------------------------------------------------------------------------- 1 | assertTrue(true); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/Models/Country.php: -------------------------------------------------------------------------------- 1 | hasMany(Area::class); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_size = 4 7 | indent_style = space 8 | insert_final_newline = false 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 | -------------------------------------------------------------------------------- /app/Http/Controllers/Controller.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /app/Http/Controllers/AdminController.php: -------------------------------------------------------------------------------- 1 | id); 13 | return view('dashboard.admin.profile', ['admin' => $admin]); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /app/Http/Middleware/VerifyCsrfToken.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "dev": "vite", 5 | "build": "vite build" 6 | }, 7 | "devDependencies": { 8 | "@popperjs/core": "^2.11.6", 9 | "axios": "^1.1.2", 10 | "bootstrap": "^5.2.3", 11 | "laravel-vite-plugin": "^0.7.2", 12 | "sass": "^1.56.1", 13 | "vite": "^4.0.0" 14 | }, 15 | "dependencies": { 16 | "chart.js": "^4.2.1" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /stubs/import.model.stub: -------------------------------------------------------------------------------- 1 | get('/'); 16 | 17 | $response->assertStatus(200); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/Models/OrderPrescription.php: -------------------------------------------------------------------------------- 1 | belongsTo(Order::class); 19 | } 20 | } -------------------------------------------------------------------------------- /app/Providers/BroadcastServiceProvider.php: -------------------------------------------------------------------------------- 1 | 2 | # We miss you! 3 | 4 | Hello {{$client->name}}, 5 | We noticed that you haven't used our application in a while. 6 | 7 |
email picture
8 | 9 | We miss you and hope to see you soon! 10 | 11 | Best Regards,
12 | {{ config('app.name') }} 13 | 14 | -------------------------------------------------------------------------------- /app/Http/Middleware/PreventRequestsDuringMaintenance.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /app/Http/Middleware/TrimStrings.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | 'current_password', 16 | 'password', 17 | 'password_confirmation', 18 | ]; 19 | } 20 | -------------------------------------------------------------------------------- /tests/CreatesApplication.php: -------------------------------------------------------------------------------- 1 | make(Kernel::class)->bootstrap(); 18 | 19 | return $app; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/Http/Middleware/TrustHosts.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | public function hosts(): array 15 | { 16 | return [ 17 | $this->allSubdomainsOfApplicationUrl(), 18 | ]; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/Providers/AppServiceProvider.php: -------------------------------------------------------------------------------- 1 | expectsJson() ? null : route('login'); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.scribe/intro.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | 4 | 5 | 8 | 9 | This documentation aims to provide all the information you need to work with our API. 10 | 11 | 13 | 14 | -------------------------------------------------------------------------------- /app/Http/Middleware/ValidateSignature.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 'fbclid', 16 | // 'utm_campaign', 17 | // 'utm_content', 18 | // 'utm_medium', 19 | // 'utm_source', 20 | // 'utm_term', 21 | ]; 22 | } 23 | -------------------------------------------------------------------------------- /app/View/Components/Modal.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | public function toArray(Request $request): array 16 | { 17 | return [ 18 | 'id'=>$this->id, 19 | 'name' => $this->name, 20 | 'type' => $this->type, 21 | ]; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /routes/channels.php: -------------------------------------------------------------------------------- 1 | id === (int) $id; 18 | }); 19 | -------------------------------------------------------------------------------- /app/Models/OrderMedicine.php: -------------------------------------------------------------------------------- 1 | belongsTo(Order::class); 21 | } 22 | public function medicine() 23 | { 24 | return $this->hasMany(Medicine::class); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /database/seeders/AdminSeeder.php: -------------------------------------------------------------------------------- 1 | 'admin', 19 | 'email' => 'admin1@admin.com', 20 | 'password' => Hash::make('123456'), 21 | 'is_admin' => true 22 | ])->assignRole('admin'); 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /database/seeders/DatabaseSeeder.php: -------------------------------------------------------------------------------- 1 | call(AreaSeeder::class); 16 | $this->call(MedicineSeeder::class); 17 | $this->call(PermissionsSeeder::class); 18 | $this->call(CountriesSeeder::class); 19 | $this->call(AdminSeeder::class); 20 | $this->command->info('Seeded the countries!'); 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /routes/console.php: -------------------------------------------------------------------------------- 1 | comment(Inspiring::quote()); 19 | })->purpose('Display an inspiring quote'); 20 | -------------------------------------------------------------------------------- /public/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | 3 | Options -MultiViews -Indexes 4 | 5 | 6 | RewriteEngine On 7 | 8 | # Handle Authorization Header 9 | RewriteCond %{HTTP:Authorization} . 10 | RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] 11 | 12 | # Redirect Trailing Slashes If Not A Folder... 13 | RewriteCond %{REQUEST_FILENAME} !-d 14 | RewriteCond %{REQUEST_URI} (.+)/$ 15 | RewriteRule ^ %1 [L,R=301] 16 | 17 | # Send Requests To Front Controller... 18 | RewriteCond %{REQUEST_FILENAME} !-d 19 | RewriteCond %{REQUEST_FILENAME} !-f 20 | RewriteRule ^ index.php [L] 21 | 22 | -------------------------------------------------------------------------------- /app/Providers/AuthServiceProvider.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | protected $policies = [ 16 | // 'App\Models\Model' => 'App\Policies\ModelPolicy', 17 | ]; 18 | 19 | /** 20 | * Register any authentication / authorization services. 21 | */ 22 | public function boot(): void 23 | { 24 | // 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Models/Area.php: -------------------------------------------------------------------------------- 1 | hasMany(Address::class); 25 | } 26 | 27 | public function country(){ 28 | return $this->belongsTo(Country::class,'country_id'); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/Http/Resources/ClientResource.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | public function toArray(Request $request): array 16 | { 17 | return [ 18 | 'id' => $this->id, 19 | 'name' => $this->name, 20 | 'gender' => $this->gender, 21 | 'email' => $this->email, 22 | 'mobile_number' => $this->mobile_number, 23 | 'national_id' => $this->national_id, 24 | ]; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /database/migrations/2023_03_27_233844_add_is_admin_to_users_table.php: -------------------------------------------------------------------------------- 1 | boolean('is_admin')->default(false); 16 | }); 17 | } 18 | 19 | /** 20 | * Reverse the migrations. 21 | */ 22 | public function down(): void 23 | { 24 | Schema::table('users', function (Blueprint $table) { 25 | // 26 | }); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /database/migrations/2023_03_31_223942_add_soft_delete_to_orders_table.php: -------------------------------------------------------------------------------- 1 | softDeletes(); 17 | }); 18 | } 19 | 20 | /** 21 | * Reverse the migrations. 22 | */ 23 | public function down(): void 24 | { 25 | Schema::table('orders', function (Blueprint $table) { 26 | // 27 | }); 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /database/migrations/2023_04_01_131515_drop_avatar_image_column_from_pharmacies_table.php: -------------------------------------------------------------------------------- 1 | dropColumn('avatar_image'); 16 | }); 17 | } 18 | 19 | /** 20 | * Reverse the migrations. 21 | */ 22 | public function down(): void 23 | { 24 | Schema::table('pharmacies', function (Blueprint $table) { 25 | 26 | }); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /database/migrations/2023_04_01_132459_drop_avatar_image_column_from_clients_table.php: -------------------------------------------------------------------------------- 1 | dropColumn('avatar_image'); 16 | }); 17 | } 18 | 19 | /** 20 | * Reverse the migrations. 21 | */ 22 | public function down(): void 23 | { 24 | Schema::table('clients', function (Blueprint $table) { 25 | // 26 | }); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /database/migrations/2023_04_01_132718_drop_avatar_image_column_from_doctors_table.php: -------------------------------------------------------------------------------- 1 | dropColumn('avatar_image'); 16 | }); 17 | } 18 | 19 | /** 20 | * Reverse the migrations. 21 | */ 22 | public function down(): void 23 | { 24 | Schema::table('doctors', function (Blueprint $table) { 25 | // 26 | }); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /database/migrations/2023_03_29_205736_add_nullable_to_userable_column_to_users_table.php: -------------------------------------------------------------------------------- 1 | nullableMorphs('userable'); 16 | 17 | }); 18 | } 19 | 20 | /** 21 | * Reverse the migrations. 22 | */ 23 | public function down(): void 24 | { 25 | Schema::table('users', function (Blueprint $table) { 26 | // 27 | }); 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /database/migrations/2023_03_30_010421_add_soft_delete_to_medicines_table.php: -------------------------------------------------------------------------------- 1 | softDeletes(); 17 | }); 18 | } 19 | 20 | /** 21 | * Reverse the migrations. 22 | */ 23 | public function down(): void 24 | { 25 | Schema::table('medicines', function (Blueprint $table) { 26 | // 27 | }); 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /database/migrations/2023_04_03_072638_add_priority_to_pharmacies_table.php: -------------------------------------------------------------------------------- 1 | integer("priority")->nullable(false); 16 | }); 17 | } 18 | 19 | /** 20 | * Reverse the migrations. 21 | */ 22 | public function down(): void 23 | { 24 | Schema::table('pharmacies', function (Blueprint $table) { 25 | // 26 | }); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /app/Http/Resources/MedicineOrderResource.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | 18 | public function toArray(Request $request): array 19 | { 20 | $medicinesInfo = Medicine::where('id', $this->id)->get(); 21 | 22 | return [ 23 | 'medicine_info'=> MedicineResource::collection($medicinesInfo), 24 | 'quantity' => $this->quantity, 25 | ]; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /database/migrations/2023_03_30_001510_add_quantity_to__medicines_table.php: -------------------------------------------------------------------------------- 1 | integer('quantity'); 17 | }); 18 | } 19 | 20 | /** 21 | * Reverse the migrations. 22 | */ 23 | public function down(): void 24 | { 25 | Schema::table('_medicines', function (Blueprint $table) { 26 | // 27 | }); 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /database/migrations/2023_04_01_141328_remove_quantity_from_medicines.php: -------------------------------------------------------------------------------- 1 | dropColumn('quantity'); 17 | }); 18 | } 19 | 20 | /** 21 | * Reverse the migrations. 22 | */ 23 | public function down(): void 24 | { 25 | Schema::table('medicines', function (Blueprint $table) { 26 | // 27 | }); 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /database/migrations/2023_04_04_102839_add_country_id_to_areas_table.php: -------------------------------------------------------------------------------- 1 | integer('country_id')->unsigned()->nullable(false); 16 | }); 17 | } 18 | 19 | /** 20 | * Reverse the migrations. 21 | */ 22 | public function down(): void 23 | { 24 | Schema::table('areas', function (Blueprint $table) { 25 | // 26 | }); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /database/migrations/2023_03_29_151018_add_usearable_column_to_users_table.php: -------------------------------------------------------------------------------- 1 | morphs('userable'); 16 | }); 17 | } 18 | 19 | /** 20 | * Reverse the migrations. 21 | */ 22 | public function down(): void 23 | { 24 | Schema::table('users', function (Blueprint $table) { 25 | $table->dropMorphs('userable'); 26 | 27 | }); 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /database/migrations/2023_03_28_144906_add_banned_at_column_to_doctors_table.php: -------------------------------------------------------------------------------- 1 | timestamp('banned_at')->nullable(); 17 | }); 18 | } 19 | 20 | /** 21 | * Reverse the migrations. 22 | */ 23 | public function down(): void 24 | { 25 | Schema::table('doctor', function (Blueprint $table) { 26 | // 27 | }); 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /database/migrations/2023_03_30_103421_add_verified_at_to_clients_table.php: -------------------------------------------------------------------------------- 1 | timestamp('email_verified_at')->nullable(); 17 | 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | */ 24 | public function down(): void 25 | { 26 | Schema::table('clients', function (Blueprint $table) { 27 | // 28 | }); 29 | } 30 | }; -------------------------------------------------------------------------------- /database/migrations/2023_04_01_140736_remove_quantity_from_order_medicines.php: -------------------------------------------------------------------------------- 1 | dropColumn('quantity'); 17 | }); 18 | } 19 | 20 | /** 21 | * Reverse the migrations. 22 | */ 23 | public function down(): void 24 | { 25 | Schema::table('order_medicines', function (Blueprint $table) { 26 | // 27 | }); 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /database/migrations/2023_04_01_141243_add_quantity_to_order_medicines_tableta.php: -------------------------------------------------------------------------------- 1 | integer('quantity'); 17 | }); 18 | } 19 | 20 | /** 21 | * Reverse the migrations. 22 | */ 23 | public function down(): void 24 | { 25 | Schema::table('order_medicines', function (Blueprint $table) { 26 | // 27 | }); 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /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/Controllers/Auth/ForgotPasswordController.php: -------------------------------------------------------------------------------- 1 | belongsTo(Area::class); 27 | } 28 | 29 | public function client() 30 | { 31 | return $this->belongsTo(Client::class); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /database/migrations/2023_03_29_205625_drop_morphs_from_users_table.php: -------------------------------------------------------------------------------- 1 | dropColumn('userable_id'); 16 | $table->dropColumn('userable_type'); 17 | 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | */ 24 | public function down(): void 25 | { 26 | Schema::table('user', function (Blueprint $table) { 27 | // 28 | }); 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /database/migrations/2023_04_01_140832_add_medicine_name_to_order_medicines_table.php: -------------------------------------------------------------------------------- 1 | string('medicine_name')->nullable(); 17 | }); 18 | } 19 | 20 | /** 21 | * Reverse the migrations. 22 | */ 23 | public function down(): void 24 | { 25 | Schema::table('order_medicines', function (Blueprint $table) { 26 | // 27 | }); 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /database/migrations/2023_04_01_141116_modify_order_medicines_table.php: -------------------------------------------------------------------------------- 1 | unsignedBigInteger('medicine_id')->nullable()->change(); 17 | }); 18 | } 19 | 20 | /** 21 | * Reverse the migrations. 22 | */ 23 | public function down(): void 24 | { 25 | Schema::table('order_medicines', function (Blueprint $table) { 26 | // 27 | }); 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /database/migrations/2014_10_12_100000_create_password_reset_tokens_table.php: -------------------------------------------------------------------------------- 1 | string('email')->primary(); 16 | $table->string('token'); 17 | $table->timestamp('created_at')->nullable(); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | */ 24 | public function down(): void 25 | { 26 | Schema::dropIfExists('password_reset_tokens'); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /database/migrations/2023_04_02_185343_modify_orders_table.php: -------------------------------------------------------------------------------- 1 | unsignedBigInteger('assigned_pharmacy_id')->nullable()->change(); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | */ 24 | public function down(): void 25 | { 26 | // 27 | Schema::table('orders', function (Blueprint $table) { 28 | // 29 | }); 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /app/Http/Requests/UpdateMedicineRequest.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function rules() 23 | { 24 | return [ 25 | 'name' => ["required", "max:255"], 26 | 'type' => ["required", "max:255"], 27 | 'price' => ["required", "integer", "min:0"], 28 | ]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /database/migrations/2023_03_29_234713_create_medicines_table.php: -------------------------------------------------------------------------------- 1 | id(); 16 | $table->string('name'); 17 | $table->integer('price'); 18 | $table->string('type'); 19 | $table->timestamps(); 20 | }); 21 | } 22 | 23 | /** 24 | * Reverse the migrations. 25 | */ 26 | public function down(): void 27 | { 28 | Schema::dropIfExists('medicines'); 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /app/Http/Requests/StoreAreaRequest.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function rules(): array 23 | { 24 | return [ 25 | 'name'=> ["required", "max:255"], 26 | 'address'=>["required", "max:255"], 27 | 'country_id' => ["required", "exists:countries,id"], 28 | ]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/Http/Requests/StoreMedicineRequest.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function rules(): array 23 | { 24 | return [ 25 | 'name' => ["required", "max:255"], 26 | 'type' => ["required", "max:255"], 27 | 'price' => ["required", "numeric", "min:0"], 28 | ]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /database/migrations/2023_03_31_015313_create_order_prescription_table.php: -------------------------------------------------------------------------------- 1 | id(); 16 | $table->string('prescription'); 17 | $table->unsignedInteger('order_id'); 18 | $table->timestamps(); 19 | }); 20 | } 21 | 22 | /** 23 | * Reverse the migrations. 24 | */ 25 | public function down(): void 26 | { 27 | Schema::dropIfExists('order_prescrptions'); 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /app/Http/Requests/UpdateAreaRequest.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function rules(): array 23 | { 24 | return [ 25 | 'name'=> ["required", "max:255"], 26 | 'address'=>["required", "max:255"], 27 | 'country_id' => ["required", "exists:countries,id"], 28 | ]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/Http/Resources/AddressResource.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | public function toArray(Request $request): array 16 | { 17 | return [ 18 | 'id' => $this->id, 19 | 'street_name' => $this->street_name, 20 | 'building_number' => $this->building_number, 21 | 'floor_number' => $this->floor_number, 22 | 'flat_number' => $this->flat_number, 23 | 'is_main' => $this->is_main, 24 | ]; 25 | // return parent::toArray($request); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /database/migrations/2023_03_26_184957_create_areas_table.php: -------------------------------------------------------------------------------- 1 | id(); 16 | $table->string('name')->nullable(false); 17 | $table->string('address')->nullable(false); 18 | $table->timestamps(); 19 | $table->softDeletes(); 20 | }); 21 | } 22 | 23 | /** 24 | * Reverse the migrations. 25 | */ 26 | public function down(): void 27 | { 28 | Schema::dropIfExists('areas'); 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/CreateOrderRequest.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function rules(): array 23 | { 24 | return [ 25 | "is_insured" => 'required|boolean', 26 | "prescription.*" => 'required|mimes:jpeg,jpg,png', 27 | "delivering_address_id" => ["required", "exists:addresses,id"] 28 | ]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /database/migrations/2023_03_31_015709_create_order_medicines_table.php: -------------------------------------------------------------------------------- 1 | id(); 16 | $table->unsignedInteger('medicine_id'); 17 | $table->integer('quantity'); 18 | $table->unsignedInteger('order_id'); 19 | $table->timestamps(); 20 | }); 21 | } 22 | 23 | /** 24 | * Reverse the migrations. 25 | */ 26 | public function down(): void 27 | { 28 | Schema::dropIfExists('order_medicines'); 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /database/migrations/2023_03_31_005432_add_creator_type_to_orders_table.php: -------------------------------------------------------------------------------- 1 | unsignedInteger('doctor_id')->nullable(); 17 | $table->string('creator_type'); 18 | $table->integer('client_address_id'); 19 | }); 20 | } 21 | 22 | /** 23 | * Reverse the migrations. 24 | */ 25 | public function down(): void 26 | { 27 | Schema::table('orders', function (Blueprint $table) { 28 | // 29 | }); 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /resources/views/emails/confirmOrder.blade.php: -------------------------------------------------------------------------------- 1 | @component('mail::message') 2 | # Order Confirmation 3 | 4 | Hello {{ $order->client->name }}, 5 | 6 | Thank you for your order. We have received your request and will process it shortly. Please find the details of your order below: 7 | 8 | **Order ID:** {{ $order->id }}
9 | **Order Date:** {{ $order->created_at }}
10 | 11 | If you would like to confirm your order, please click the button below: 12 | 13 | @component('mail::button', ['url' => route('stripe', ['id' => $order->id])]) 14 | Confirm Order 15 | @endcomponent 16 | 17 | If you would like to cancel your order, please click the button below: 18 | 19 | @component('mail::button', ['url' => route('order.orderCancel', $order->id)]) 20 | Cancel Order 21 | @endcomponent 22 | 23 | 24 | Thank you for your business! 25 | 26 | Regards,
27 | The DrugRadar Team 28 | @endcomponent 29 | -------------------------------------------------------------------------------- /app/Models/Medicine.php: -------------------------------------------------------------------------------- 1 | belongsToMany(OrderMedicine::class); 26 | } 27 | 28 | protected function price(): Attribute 29 | { 30 | return Attribute::make( 31 | get: fn (int $value) => ($value/100), 32 | set : fn (int $value) => ($value*100), 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/Http/Middleware/RedirectIfAuthenticated.php: -------------------------------------------------------------------------------- 1 | check()) { 24 | return redirect(RouteServiceProvider::HOME); 25 | } 26 | } 27 | 28 | return $next($request); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/Notifications/ClientVerified.php: -------------------------------------------------------------------------------- 1 | subject('Welcome to our site!') 26 | ->greeting('Hello ' . $notifiable->name . ',') 27 | ->line('We wanted to take a moment to welcome you to our site.') 28 | ->line('Thank you for verifying your email address.'); 29 | 30 | } 31 | 32 | public function toArray($notifiable) 33 | { 34 | return [ 35 | // 36 | ]; 37 | } 38 | } -------------------------------------------------------------------------------- /database/migrations/2019_08_19_000000_create_failed_jobs_table.php: -------------------------------------------------------------------------------- 1 | id(); 16 | $table->string('uuid')->unique(); 17 | $table->text('connection'); 18 | $table->text('queue'); 19 | $table->longText('payload'); 20 | $table->longText('exception'); 21 | $table->timestamp('failed_at')->useCurrent(); 22 | }); 23 | } 24 | 25 | /** 26 | * Reverse the migrations. 27 | */ 28 | public function down(): void 29 | { 30 | Schema::dropIfExists('failed_jobs'); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /database/migrations/2023_03_31_002808_create_orders_table.php: -------------------------------------------------------------------------------- 1 | id(); 16 | $table->string('status'); 17 | $table->unsignedBigInteger('assigned_pharmacy_id'); 18 | $table->bigInteger('total_price')->nullable(); 19 | $table->unsignedBigInteger('client_id'); 20 | $table->boolean('is_insured')->nullable(false); 21 | $table->timestamps(); 22 | }); 23 | } 24 | 25 | /** 26 | * Reverse the migrations. 27 | */ 28 | public function down(): void 29 | { 30 | Schema::dropIfExists('orders'); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /database/migrations/2014_10_12_000000_create_users_table.php: -------------------------------------------------------------------------------- 1 | id(); 16 | $table->string('name')->nullable(false); 17 | $table->string('email')->unique(); 18 | $table->timestamp('email_verified_at')->nullable(); 19 | $table->string('password'); 20 | $table->rememberToken(); 21 | $table->timestamps(); 22 | $table->softDeletes(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | */ 29 | public function down(): void 30 | { 31 | Schema::dropIfExists('users'); 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /resources/views/vendor/scribe/themes/default/groups.blade.php: -------------------------------------------------------------------------------- 1 | @foreach($groupedEndpoints as $group) 2 |

{!! $group['name'] !!}

3 | 4 | {!! Parsedown::instance()->text($group['description']) !!} 5 | 6 | @foreach($group['subgroups'] as $subgroupName => $subgroup) 7 | @if($subgroupName !== "") 8 |

{{ $subgroupName }}

9 | @php($subgroupDescription = collect($subgroup)->first(fn ($e) => $e->metadata->subgroupDescription)?->metadata?->subgroupDescription) 10 | @if($subgroupDescription) 11 |

12 | {!! Parsedown::instance()->text($subgroupDescription) !!} 13 |

14 | @endif 15 | @endif 16 | @foreach($subgroup as $endpoint) 17 | @include("scribe::themes.default.endpoint") 18 | @endforeach 19 | @endforeach 20 | @endforeach 21 | 22 | -------------------------------------------------------------------------------- /app/Http/Controllers/Auth/ResetPasswordController.php: -------------------------------------------------------------------------------- 1 | subDays(3)) 30 | ->get(); 31 | 32 | foreach ($doctorsToUnban as $doctor) { 33 | $doctor->banned_at = Null; 34 | $doctor->save(); 35 | } 36 | 37 | $this->info(count($doctorsToUnban) . ' users have been unbanned.'); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /database/seeders/AreaSeeder.php: -------------------------------------------------------------------------------- 1 | 'Smouha', 19 | 'address' => '26 smouha', 20 | 'country_id' => '818', 21 | ], 22 | [ 23 | 'name' => 'Sidibishr', 24 | 'address' => '16 mahmoud reda', 25 | 'country_id' => '818', 26 | ], 27 | [ 28 | 'name' => 'campchizar', 29 | 'address' => '46 helipolis', 30 | 'country_id' => '818', 31 | ], 32 | ]; 33 | 34 | foreach($areas as $area){ 35 | Area::create($area); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php: -------------------------------------------------------------------------------- 1 | id(); 16 | $table->morphs('tokenable'); 17 | $table->string('name'); 18 | $table->string('token', 64)->unique(); 19 | $table->text('abilities')->nullable(); 20 | $table->timestamp('last_used_at')->nullable(); 21 | $table->timestamp('expires_at')->nullable(); 22 | $table->timestamps(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | */ 29 | public function down(): void 30 | { 31 | Schema::dropIfExists('personal_access_tokens'); 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /app/Providers/EventServiceProvider.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 | public function boot(): void 27 | { 28 | // 29 | } 30 | 31 | /** 32 | * Determine if events and listeners should be automatically discovered. 33 | */ 34 | public function shouldDiscoverEvents(): bool 35 | { 36 | return false; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/Console/Commands/NotifyInactiveClients.php: -------------------------------------------------------------------------------- 1 | subMonth())->get(); 33 | foreach ( $clients as $client ) { 34 | Mail::to($client->email)->send(new InactiveClientMail($client)); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/Http/Controllers/StripeController.php: -------------------------------------------------------------------------------- 1 | query('id'))->firstOrFail(); 14 | return view('stripe' , ["order" => $order]); 15 | } 16 | public function stripePost(Request $request) 17 | { 18 | $order = Order::find( $request->order_id); 19 | Stripe\Stripe::setApiKey(env('STRIPE_SECRET')); 20 | Stripe\Charge::create ([ 21 | "amount" => $order-> total_price, 22 | "currency" => "usd", 23 | "source" => $request->stripeToken, 24 | "description" => "pay for medicines order" 25 | ]); 26 | 27 | Session::flash('success', 'Payment successful!'); 28 | 29 | return to_route('order.orderConfirm' , ['id'=>$request->order_id]); 30 | } 31 | } -------------------------------------------------------------------------------- /resources/views/components/modal.blade.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /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(): array 19 | { 20 | return [ 21 | 'name' => fake()->name(), 22 | 'email' => fake()->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 | public function unverified(): static 33 | { 34 | return $this->state(fn (array $attributes) => [ 35 | 'email_verified_at' => null, 36 | ]); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /database/migrations/2023_03_26_185023_create_pharmacies_table.php: -------------------------------------------------------------------------------- 1 | id(); 16 | $table->unsignedBigInteger('area_id')->nullable(false); 17 | $table->string('name'); 18 | $table->string('email')->unique(); 19 | $table->string('password'); 20 | $table->string('national_id')->unique(); 21 | $table->string('avatar_image')->nullable()->default(null); 22 | $table->foreign('area_id')->references('id')->on('areas'); 23 | $table->timestamps(); 24 | $table->softDeletes(); 25 | }); 26 | } 27 | 28 | /** 29 | * Reverse the migrations. 30 | */ 31 | public function down(): void 32 | { 33 | Schema::dropIfExists('pharmacies'); 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /database/seeders/MedicineSeeder.php: -------------------------------------------------------------------------------- 1 | 'zyrtec', 19 | 'type' => 'antihistaminic', 20 | 'price' =>'50', 21 | ], 22 | [ 23 | 'name' => 'concor', 24 | 'type' => 'antihypertensive', 25 | 'price' =>'60', 26 | ], 27 | [ 28 | 'name' => 'Brufen', 29 | 'type' => 'painkiller', 30 | 'price' =>'40', 31 | ], 32 | [ 33 | 'name' => 'adancor', 34 | 'type' => 'antihypertensive', 35 | 'price' =>'90', 36 | ], 37 | 38 | ]; 39 | 40 | foreach ($medicines as$medicine){ 41 | Medicine::create($medicine); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/ClientRegisterRequest.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function rules(): array 23 | { 24 | 25 | return [ 26 | 'name' => 'required|string|max:255', 27 | 'email' => 'required|email|unique:clients,email', 28 | 'gender' => 'required|in:male,female', 29 | 'password' => 'required|string|min:6', 30 | 'date_of_birth' => 'required|date|before_or_equal:today', 31 | 'avatar_image' => 'required|image|max:2048', 32 | 'mobile_number' => 'required|string|max:20', 33 | 'national_id' => 'required|integer|digits:14|unique:clients,national_id', 34 | ]; 35 | } 36 | } -------------------------------------------------------------------------------- /app/Http/Controllers/Auth/LoginController.php: -------------------------------------------------------------------------------- 1 | middleware('guest')->except('logout'); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /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 | 'stripe' => [ 34 | 'secret' => env('STRIPE_SECRET'), 35 | ], 36 | 37 | ]; 38 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /app/Console/Commands/CreateAdminCommand.php: -------------------------------------------------------------------------------- 1 | option('email'); 31 | $password = $this->option('password'); 32 | 33 | $user = new User; 34 | $user->name = 'Admin'; 35 | $user->email = $email; 36 | $user->password = bcrypt($password); 37 | $user->is_admin = true; 38 | $user->assignRole(['admin']); 39 | $user->save(); 40 | 41 | $this->info('Admin user created successfully!'); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/ClientUpdateProfileRequest.php: -------------------------------------------------------------------------------- 1 | 22 | */ 23 | public function rules():array 24 | { 25 | // return [$this] ; 26 | return [ 27 | 'name' => 'sometimes|required|string|max:255', 28 | 'gender' => 'sometimes|required|in:male,female', 29 | 'date_of_birth' => 'sometimes|required|date|before_or_equal:today', 30 | 'avatar_image' => 'nullable|image|max:2048', 31 | 'mobile_number' => 'sometimes|required|string|max:20', 32 | 'national_id' => 'sometimes|required|string|max:20|unique:clients,national_id,' . $this->id, 33 | ]; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /database/migrations/2023_04_01_124824_create_media_table.php: -------------------------------------------------------------------------------- 1 | id(); 13 | 14 | $table->morphs('model'); 15 | $table->uuid('uuid')->nullable()->unique(); 16 | $table->string('collection_name'); 17 | $table->string('name'); 18 | $table->string('file_name'); 19 | $table->string('mime_type')->nullable(); 20 | $table->string('disk'); 21 | $table->string('conversions_disk')->nullable(); 22 | $table->unsignedBigInteger('size'); 23 | $table->json('manipulations'); 24 | $table->json('custom_properties'); 25 | $table->json('generated_conversions'); 26 | $table->json('responsive_images'); 27 | $table->unsignedInteger('order_column')->nullable()->index(); 28 | 29 | $table->nullableTimestamps(); 30 | }); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /app/Http/Controllers/Auth/ConfirmPasswordController.php: -------------------------------------------------------------------------------- 1 | middleware('auth'); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/Console/Kernel.php: -------------------------------------------------------------------------------- 1 | command('app:notify-inactive-clients')->daily(); 20 | $schedule->command('orders:scan-new-orders')->everyMinute(); 21 | $schedule->command('unban-doctor')->dailyAt('00:00'); 22 | 23 | } 24 | protected $commands = [ 25 | CreateAdminCommand::class, 26 | NotifyInactiveClients::class, 27 | UnbanUserCommand::class, 28 | ScanNewOrders::class, 29 | ]; 30 | /** 31 | * Register the commands for the application. 32 | */ 33 | protected function commands(): void 34 | { 35 | $this->load(__DIR__.'/Commands'); 36 | 37 | require base_path('routes/console.php'); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /resources/views/vendor/scribe/themes/elements/groups.blade.php: -------------------------------------------------------------------------------- 1 | @foreach($groupedEndpoints as $group) 2 |

5 | {!! $group['name'] !!} 6 |

7 | 8 | {!! Parsedown::instance()->text($group['description']) !!} 9 | 10 | @foreach($group['subgroups'] as $subgroupName => $subgroup) 11 | @if($subgroupName !== "") 12 |

15 | {{ $subgroupName }} 16 |

17 | @php($subgroupDescription = collect($subgroup)->first(fn ($e) => $e->metadata->subgroupDescription)?->metadata?->subgroupDescription) 18 | @if($subgroupDescription) 19 | {!! Parsedown::instance()->text($subgroupDescription) !!} 20 | @endif 21 |
22 | @endif 23 | @foreach($subgroup as $endpoint) 24 | @include("scribe::themes.elements.endpoint") 25 | @endforeach 26 | @endforeach 27 | @endforeach 28 | 29 | -------------------------------------------------------------------------------- /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 to the session on 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 | public function register(): void 43 | { 44 | $this->reportable(function (Throwable $e) { 45 | // 46 | }); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /app/Models/Order.php: -------------------------------------------------------------------------------- 1 | hasMany(OrderMedicine::class); 32 | } 33 | public function orderPrescription() 34 | { 35 | return $this->hasMany(OrderPrescription::class); 36 | } 37 | public function client(){ 38 | return $this->belongsTo(Client::class); 39 | } 40 | public function doctor(){ 41 | return $this->belongsTo(Doctor::class); 42 | } 43 | } -------------------------------------------------------------------------------- /database/migrations/2023_03_28_080759_create_doctors_table.php: -------------------------------------------------------------------------------- 1 | id(); 16 | $table->unsignedBigInteger('pharmacy_id')->nullable(false); 17 | $table->string('name'); 18 | $table->string('email')->unique(); 19 | $table->string('password'); 20 | $table->string('national_id')->unique(); 21 | $table->string('avatar_image')->nullable()->default(null); 22 | // $table->foreign('pharmacy_id')->references('id')->on('pharmacies'); 23 | $table->foreign('pharmacy_id')->references('id')->on('pharmacies')->onDelete('cascade'); 24 | $table->timestamps(); 25 | $table->softDeletes(); 26 | }); 27 | } 28 | 29 | /** 30 | * Reverse the migrations. 31 | */ 32 | public function down(): void 33 | { 34 | Schema::dropIfExists('doctors'); 35 | } 36 | }; -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /app/Models/Doctor.php: -------------------------------------------------------------------------------- 1 | belongsTo(Pharmacy::class); 37 | } 38 | 39 | public function user(){ 40 | return $this->morphOne(User::class, 'userable'); 41 | } 42 | 43 | 44 | } -------------------------------------------------------------------------------- /resources/js/bootstrap.js: -------------------------------------------------------------------------------- 1 | import 'bootstrap'; 2 | 3 | /** 4 | * We'll load the axios HTTP library which allows us to easily issue requests 5 | * to our Laravel back-end. This library automatically handles sending the 6 | * CSRF token as a header based on the value of the "XSRF" token cookie. 7 | */ 8 | 9 | import axios from 'axios'; 10 | window.axios = axios; 11 | 12 | window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; 13 | 14 | /** 15 | * Echo exposes an expressive API for subscribing to channels and listening 16 | * for events that are broadcast by Laravel. Echo and event broadcasting 17 | * allows your team to easily build robust real-time web applications. 18 | */ 19 | 20 | // import Echo from 'laravel-echo'; 21 | 22 | // import Pusher from 'pusher-js'; 23 | // window.Pusher = Pusher; 24 | 25 | // window.Echo = new Echo({ 26 | // broadcaster: 'pusher', 27 | // key: import.meta.env.VITE_PUSHER_APP_KEY, 28 | // wsHost: import.meta.env.VITE_PUSHER_HOST ?? `ws-${import.meta.env.VITE_PUSHER_APP_CLUSTER}.pusher.com`, 29 | // wsPort: import.meta.env.VITE_PUSHER_PORT ?? 80, 30 | // wssPort: import.meta.env.VITE_PUSHER_PORT ?? 443, 31 | // forceTLS: (import.meta.env.VITE_PUSHER_SCHEME ?? 'https') === 'https', 32 | // enabledTransports: ['ws', 'wss'], 33 | // }); 34 | -------------------------------------------------------------------------------- /.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=mailpit 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_HOST= 50 | PUSHER_PORT=443 51 | PUSHER_SCHEME=https 52 | PUSHER_APP_CLUSTER=mt1 53 | 54 | VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}" 55 | VITE_PUSHER_HOST="${PUSHER_HOST}" 56 | VITE_PUSHER_PORT="${PUSHER_PORT}" 57 | VITE_PUSHER_SCHEME="${PUSHER_SCHEME}" 58 | VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" 59 | -------------------------------------------------------------------------------- /database/migrations/2023_03_29_173324_create_clients_table.php: -------------------------------------------------------------------------------- 1 | id(); 16 | $table->string('name')->nullable(false); 17 | $table->string('email')->nullable(false)->unique(); 18 | $table->enum('gender', ['male', 'female'])->nullable(false); 19 | $table->string('password')->nullable(false); 20 | $table->date('date_of_birth')->nullable(false); 21 | $table->string('national_id')->nullable(false)->unique(); 22 | $table->string('mobile_number')->nullable(false); 23 | $table->string('avatar_image')->nullable(false); 24 | $table->timestamp('last_visit')->nullable(); 25 | $table->timestamps(); 26 | $table->softDeletes(); 27 | }); 28 | } 29 | 30 | /** 31 | * Reverse the migrations. 32 | */ 33 | public function down(): void 34 | { 35 | Schema::dropIfExists('clients'); 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /app/Http/Controllers/Auth/VerificationController.php: -------------------------------------------------------------------------------- 1 | middleware('auth'); 39 | $this->middleware('signed')->only('verify'); 40 | $this->middleware('throttle:6,1')->only('verify', 'resend'); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/Http/Requests/StoreDoctorRequest.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function rules(): array 23 | { 24 | return [ 25 | 'name' => ['required', "max:255"], 26 | 'email' => ['required', "max:255", "max:255",'unique:users,email','email'], 27 | 'password' => ['required', "max:255",'min:6'], 28 | 'national_id' => ['required','integer','digits:14','unique:doctors,national_id'], 29 | 'avatar_image' => ['image', "max:255",'mimes:jpeg,jpg,png'], 30 | 'pharmacy_id' => ["required",'exists:pharmacies,id'], 31 | ]; 32 | } 33 | 34 | public function messages() 35 | { 36 | return [ 37 | 'pharmacy_id.exists' => "This pharmacy is invalid.", 38 | 'pharmacy_id.required' => "The pharmacy is required.", 39 | ]; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /database/migrations/2023_03_29_201635_create_addresses_table.php: -------------------------------------------------------------------------------- 1 | id(); 16 | $table->unsignedBigInteger('area_id')->nullable(false); 17 | $table->string('street_name')->nullable(false); 18 | $table->integer('building_number')->nullable(false); 19 | $table->integer('floor_number')->nullable(false); 20 | $table->integer('flat_number')->nullable(false); 21 | $table->boolean('is_main')->nullable(false); 22 | $table->unsignedBigInteger('client_id')->nullable(false); 23 | $table->foreign('area_id')->references('id')->on('areas'); 24 | $table->foreign('client_id')->references('id')->on('clients'); 25 | $table->timestamps(); 26 | $table->softDeletes(); 27 | }); 28 | } 29 | 30 | /** 31 | * Reverse the migrations. 32 | */ 33 | public function down(): void 34 | { 35 | Schema::dropIfExists('addresses'); 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /app/Mail/ConfirmOrder.php: -------------------------------------------------------------------------------- 1 | orderData = $orderData; 22 | 23 | } 24 | 25 | /** 26 | * Get the message envelope. 27 | */ 28 | public function envelope(): Envelope 29 | { 30 | return new Envelope( 31 | subject: 'Confirm Order', 32 | ); 33 | } 34 | 35 | /** 36 | * Get the message content definition. 37 | */ 38 | public function content(): Content 39 | { 40 | return new Content( 41 | markdown: 'emails.confirmOrder', 42 | with: ['order' => $this->orderData], 43 | ); 44 | } 45 | 46 | /** 47 | * Get the attachments for the message. 48 | * 49 | * @return array 50 | */ 51 | public function attachments(): array 52 | { 53 | return []; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /app/Models/User.php: -------------------------------------------------------------------------------- 1 | 22 | */ 23 | protected $fillable = [ 24 | 'name', 25 | 'email', 26 | 'password', 27 | ]; 28 | 29 | /** 30 | * The attributes that should be hidden for serialization. 31 | * 32 | * @var array 33 | */ 34 | protected $hidden = [ 35 | 'password', 36 | 'remember_token', 37 | ]; 38 | 39 | /** 40 | * The attributes that should be cast. 41 | * 42 | * @var array 43 | */ 44 | protected $casts = [ 45 | 'email_verified_at' => 'datetime', 46 | ]; 47 | public function userable() 48 | { 49 | return $this->morphTo(); 50 | } 51 | 52 | 53 | 54 | 55 | } 56 | -------------------------------------------------------------------------------- /database/migrations/2017_03_04_000000_create_bans_table.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | declare(strict_types=1); 13 | 14 | use Illuminate\Database\Migrations\Migration; 15 | use Illuminate\Database\Schema\Blueprint; 16 | use Illuminate\Support\Facades\Schema; 17 | 18 | class CreateBansTable extends Migration 19 | { 20 | /** 21 | * Run the migrations. 22 | * 23 | * @return void 24 | */ 25 | public function up(): void 26 | { 27 | Schema::create('bans', function (Blueprint $table) { 28 | $table->increments('id'); 29 | $table->morphs('bannable'); 30 | $table->nullableMorphs('created_by'); 31 | $table->text('comment')->nullable(); 32 | $table->timestamp('expired_at')->nullable(); 33 | $table->softDeletes(); 34 | $table->timestamps(); 35 | 36 | $table->index('expired_at'); 37 | }); 38 | } 39 | 40 | /** 41 | * Reverse the migrations. 42 | * 43 | * @return void 44 | */ 45 | public function down(): void 46 | { 47 | Schema::dropIfExists('bans'); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /app/Http/Requests/Api/AddressRegisterRequest.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function rules(): array 23 | { 24 | return [ 25 | 'street_name' => ["required" , "max:255"], 26 | 'building_number' => ["required" , "integer" , "min:1"], 27 | 'floor_number' => ["required" , "integer" , "min:1"], 28 | 'flat_number' => ["required" , "integer" , "min:1"], 29 | 'is_main' => ["required", 'in:0,1'], 30 | 'area_id' => ["required", "exists:areas,id"], 31 | ]; 32 | } 33 | 34 | public function messages() 35 | { 36 | return [ 37 | 'area_id.required' => "The area field is required.", 38 | 'area_id.exists' => "This selected option is invalid.", 39 | 'is_main.required' => "The Main field is required." 40 | ]; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/Http/Requests/StorePharmacyRequest.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function rules(): array 23 | { 24 | return [ 25 | 'name' => ['required', "max:255"], 26 | 'email' => ['required', "max:255",'unique:users,email','email'], 27 | 'password' => ['required', "max:255",'min:6'], 28 | 'national_id' => ['required','integer','digits:14','unique:pharmacies,national_id'], 29 | 'avatar_image' => ['image', "max:255",'mimes:jpeg,jpg,png'], 30 | 'area_id' => ["required", "exists:areas,id"], 31 | 'priority' => ['required', 'integer', "min:0"] 32 | ]; 33 | } 34 | 35 | public function messages() 36 | { 37 | return [ 38 | 'area_id.exists' => "This area is invalid.", 39 | 'area_id.required' => "The area is required." 40 | ]; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /public/css/emailCard.css: -------------------------------------------------------------------------------- 1 | body { 2 | height: 100vh; 3 | } 4 | .view { 5 | display: flex; 6 | flex-direction: column; 7 | align-items: center; 8 | justify-content: center; 9 | background-color: #f4f6f6; 10 | height: 100vh; 11 | } 12 | 13 | .card { 14 | display: flex; 15 | flex-shrink: 1; 16 | flex-direction: row; 17 | width: calc(100vh - 2 * 1rem); 18 | height: calc(55vh - 2 * 1.25rem); 19 | background-color: #fff; 20 | box-shadow: 0px 0px 10px 1px rgba(0, 0, 0, 0.2); 21 | border-radius: 1.5rem; 22 | padding: 1.25rem 1rem; 23 | } 24 | 25 | .wraper { 26 | display: flex; 27 | flex-direction: row; 28 | flex: 1; 29 | } 30 | 31 | .left-panel { 32 | display: flex; 33 | align-items: center; 34 | flex-direction: column; 35 | justify-content: center; 36 | } 37 | 38 | .media-wrapper { 39 | display: flex; 40 | height: 35vh; 41 | width: 35vh; 42 | } 43 | 44 | .media { 45 | display: flex; 46 | flex: 1; 47 | flex-direction: column; 48 | height: 100%; 49 | } 50 | 51 | .figure { 52 | display: flex; 53 | flex: 1; 54 | margin: 0; 55 | background: no-repeat center/contain; 56 | } 57 | 58 | .right-panel { 59 | display: flex; 60 | flex: 1; 61 | flex-direction: column; 62 | margin-top: 1.5rem; 63 | align-items: center; 64 | } 65 | 66 | .right-panel > p { 67 | text-align: center; 68 | } 69 | -------------------------------------------------------------------------------- /app/Mail/InactiveClientMail.php: -------------------------------------------------------------------------------- 1 | client = $client; 25 | } 26 | 27 | /** 28 | * Get the message envelope. 29 | */ 30 | public function envelope(): Envelope 31 | { 32 | return new Envelope( 33 | subject: 'Inactive Client Mail', 34 | ); 35 | } 36 | 37 | /** 38 | * Get the message content definition. 39 | */ 40 | public function content(): Content 41 | { 42 | return new Content( 43 | markdown: 'emails.inactiveClient', 44 | with: [ 45 | 'client' => $this->client, 46 | ] 47 | ); 48 | } 49 | 50 | /** 51 | * Get the attachments for the message. 52 | * 53 | * @return array 54 | */ 55 | public function attachments(): array 56 | { 57 | return []; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /app/Http/Resources/OrderResource.php: -------------------------------------------------------------------------------- 1 | 17 | */ 18 | public function toArray(Request $request): array 19 | { 20 | 21 | $pharmacyInfo = Pharmacy::where('id', $this->assigned_pharmacy_id)->first(); 22 | // $medicineIds = OrderMedicine::where('order_id', $this->id)->pluck('medicine_id'); 23 | $orderMedicine = OrderMedicine::where('order_id', $this->id)->get(); 24 | // $medicinesInfo = Medicine::whereIn('id', $medicineIds)->get(); 25 | // $append = [$medicineIds , $medicinesInfo]; 26 | 27 | return [ 28 | 'id' => $this->id, 29 | 'medicines' => MedicineOrderResource::collection($orderMedicine), 30 | 'order_total_price' => $this->total_price, 31 | 'ordered_at' => $this->created_at->diffForHumans(), 32 | 'status' => $this->status, 33 | 'assigned_pharmacy' => [ 34 | 'id' => $pharmacyInfo->id, 35 | 'name' => $pharmacyInfo->name, 36 | 'area_id' => $pharmacyInfo->area_id, 37 | ] 38 | ]; 39 | } 40 | } -------------------------------------------------------------------------------- /resources/views/vendor/scribe/themes/elements/components/nested-fields.blade.php: -------------------------------------------------------------------------------- 1 | @php 2 | $level ??= 0; 3 | $levelNestingClass = match($level) { 4 | 0 => "sl-ml-px", 5 | default => "sl-ml-7" 6 | }; 7 | $expandable ??= !isset($fields["[]"]); 8 | @endphp 9 | 10 | @foreach($fields as $name => $field) 11 |
12 | @component('scribe::themes.elements.components.field-details', [ 13 | 'name' => $name, 14 | 'type' => $field['type'] ?? 'string', 15 | 'required' => $field['required'] ?? false, 16 | 'description' => $field['description'] ?? '', 17 | 'example' => $field['example'] ?? '', 18 | 'endpointId' => $endpointId, 19 | 'hasChildren' => !empty($field['__fields']), 20 | 'component' => 'body', 21 | ]) 22 | @endcomponent 23 | 24 | @if(!empty($field['__fields'])) 25 |
26 | @component('scribe::themes.elements.components.nested-fields', [ 27 | 'fields' => $field['__fields'], 28 | 'endpointId' => $endpointId, 29 | 'level' => $level + 1, 30 | 'expandable'=> $expandable, 31 | ]) 32 | @endcomponent 33 |
34 | @endif 35 |
36 | @endforeach 37 | -------------------------------------------------------------------------------- /app/Mail/WelcomeMail.php: -------------------------------------------------------------------------------- 1 | client = $client; 24 | } 25 | 26 | /** 27 | * Get the message envelope. 28 | */ 29 | public function envelope(): Envelope 30 | { 31 | return new Envelope( 32 | subject: 'Welcome Mail', 33 | ); 34 | } 35 | 36 | /** 37 | * Get the message content definition. 38 | */ 39 | public function content(): Content 40 | { 41 | return new Content( 42 | markdown: 'emails.welcome', 43 | ); 44 | } 45 | 46 | // public function build() 47 | // { 48 | // return $this->subject('Welcome to our application') 49 | // ->markdown('emails.welcome'); 50 | // } 51 | 52 | /** 53 | * Get the attachments for the message. 54 | * 55 | * @return array 56 | */ 57 | public function attachments(): array 58 | { 59 | return []; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/Providers/RouteServiceProvider.php: -------------------------------------------------------------------------------- 1 | configureRateLimiting(); 28 | 29 | $this->routes(function () { 30 | Route::middleware('api') 31 | ->prefix('api') 32 | ->group(base_path('routes/api.php')); 33 | 34 | Route::middleware('web') 35 | ->group(base_path('routes/web.php')); 36 | }); 37 | } 38 | 39 | /** 40 | * Configure the rate limiters for the application. 41 | */ 42 | protected function configureRateLimiting(): void 43 | { 44 | RateLimiter::for('api', function (Request $request) { 45 | return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip()); 46 | }); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /public/css/DarkToggleStyle.css: -------------------------------------------------------------------------------- 1 | .Dark-btn { 2 | position: relative; 3 | width: 110px; 4 | height: 50px; 5 | display: block; 6 | background: url("../assets/gifs/LightMode.gif"); 7 | background-size: cover; 8 | background-position: center; 9 | border: 4px solid rgba(197, 151, 23, 0.3); border-radius: 100px; 10 | cursor: pointer; transition: 1s ease; 11 | box-shadow: ℗ ℗ 25px rgba(0, 0, 0, 0.2); 12 | } 13 | 14 | .Dark-btn::after { 15 | content: ""; 16 | position: absolute; 17 | height: 30px; 18 | width: 30px; 19 | background: #f2f2f2; 20 | border-radius: 50%; 21 | top: 5px; 22 | left: 5px; 23 | transition: 0.8s ease; 24 | box-shadow:0 10px rgba(0, 0, 0, 0.2); 25 | } 26 | 27 | .Dark-btn::before { 28 | content: ""; 29 | position: absolute; 30 | height: 32px; 31 | width: 32px; 32 | border: 1px solid rgba(198, 247, 253, 0.3); 33 | border-radius: 50%; 34 | top: 4px; 35 | left: 4px; 36 | transition: 0.8s ease; 37 | box-shadow:0 8px rgba(0, 0, 0, 0.18); 38 | } 39 | 40 | #dark-mode:checked ~ .Dark-btn::after { 41 | left: 94px; 42 | transform: translateX(-100%); 43 | background: #777ba5; 44 | } 45 | 46 | #dark-mode:checked ~ .Dark-btn::before { 47 | left: 97px; 48 | border: 1px solid rgba(90, 79, 136, 0.2); 49 | transform: translateX(-100%); 50 | } 51 | 52 | #dark-mode:checked ~ .Dark-btn { 53 | background: url('../assets/gifs/DarkMode\ .gif'); 54 | background-size: cover; 55 | background-position: center; 56 | border: 4px solid rgba(90,79,136,0.2); 57 | } 58 | 59 | #dark-mode { 60 | display: none; 61 | } -------------------------------------------------------------------------------- /app/Http/Requests/StoreAddressRequest.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function rules(): array 23 | { 24 | return [ 25 | 'street_name' => ["required" , "max:255"], 26 | 'building_number' => ["required" , "integer" , "min:1"], 27 | 'floor_number' => ["required" , "integer" , "min:1"], 28 | 'flat_number' => ["required" , "integer" , "min:1"], 29 | 'is_main' => ["required", 'in:0,1'], 30 | 'area_id' => ["required", "exists:areas,id"], 31 | 'client_id' => ["required", "exists:clients,id"] 32 | ]; 33 | } 34 | 35 | public function messages() 36 | { 37 | return [ 38 | 'area_id.required' => "The area field is required.", 39 | 'area_id.exists' => "This selected option is invalid.", 40 | 'client_id.required' => "The client field is required.", 41 | 'client_id.exists' => "This selected option is invalid.", 42 | 'is_main.required' => "The Main field is required." 43 | ]; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/Http/Requests/UpdateAddressRequest.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function rules(): array 23 | { 24 | return [ 25 | 'street_name' => ["required" , "max:255"], 26 | 'building_number' => ["required" , "integer" , "min:1"], 27 | 'floor_number' => ["required" , "integer" , "min:1"], 28 | 'flat_number' => ["required" , "integer" , "min:1"], 29 | 'is_main' => ["required", 'in:0,1'], 30 | 'area_id' => ["required", "exists:areas,id"], 31 | 'client_id' => ["required", "exists:clients,id"] 32 | ]; 33 | } 34 | 35 | public function messages() 36 | { 37 | return [ 38 | 'area_id.required' => "The area field is required.", 39 | 'area_id.exists' => "This selected option is invalid.", 40 | 'client_id.required' => "The client field is required.", 41 | 'client_id.exists' => "This selected option is invalid.", 42 | 'is_main.required' => "The Main field is required." 43 | ]; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /resources/views/welcome.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 |
16 |
17 | 18 | 19 | 20 |
21 |

DrugRadar 22 | 23 |

24 |

Navigating the world of pharmaceuticals, One click at a time!

25 |
26 |
27 | 28 | 29 |  Dashboard  30 | 31 | 32 | 33 |
34 |
35 | 36 | 37 | -------------------------------------------------------------------------------- /app/Console/Commands/ScanNewOrders.php: -------------------------------------------------------------------------------- 1 | get(); 32 | $new_orders = DB::table('orders') 33 | ->where('status', 'new') 34 | ->get(); 35 | foreach ($new_orders as $order) { 36 | $pharmacy = null; 37 | foreach ($pharmacies as $p) { 38 | $address = Address::where('id',$order->client_address_id)->first(); 39 | if ($p->area_id == $address->area_id) { 40 | if ($pharmacy == null || $p->priority > $pharmacy->priority) { 41 | $pharmacy = $p; 42 | } 43 | } 44 | } 45 | if ($pharmacy != null) { 46 | DB::table('orders') 47 | ->where('id', $order->id) 48 | ->update(['status' => 'processing', 'assigned_pharmacy_id' => $pharmacy->id]); 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/Models/Pharmacy.php: -------------------------------------------------------------------------------- 1 | belongsTo(Area::class); 41 | } 42 | public function user() 43 | { 44 | return $this->morphOne(User::class, 'userable'); 45 | } 46 | protected static function boot() 47 | { 48 | parent::boot(); 49 | 50 | static::deleting(function ($parent) { 51 | $parent->doctor()->delete(); // Delete all child records 52 | }); 53 | } 54 | 55 | public function doctor(){ 56 | return $this->hasMany(Doctor::class); 57 | } 58 | 59 | } -------------------------------------------------------------------------------- /app/Models/Client.php: -------------------------------------------------------------------------------- 1 | hasMany(Address::class); 33 | } 34 | 35 | public function order() 36 | { 37 | return $this->hasMany(Order::class); 38 | } 39 | public function hasVerifiedEmail() 40 | { 41 | return ! is_null($this->email_verified_at); 42 | } 43 | 44 | public function markEmailAsVerified() 45 | { 46 | $this->forceFill([ 47 | 'email_verified_at' => $this->freshTimestamp(), 48 | ])->save(); 49 | } 50 | 51 | public function sendEmailVerificationNotification() 52 | { 53 | $this->notify(new \Illuminate\Auth\Notifications\VerifyEmail); 54 | } 55 | 56 | public function getEmailForVerification() 57 | { 58 | return $this->email; 59 | } 60 | } -------------------------------------------------------------------------------- /database/migrations/2023_04_03_153548_setup_countries_table.php: -------------------------------------------------------------------------------- 1 | integer('id')->unsigned()->index(); 18 | $table->string('capital', 255)->nullable(); 19 | $table->string('citizenship', 255)->nullable(); 20 | $table->string('country_code', 3)->default(''); 21 | $table->string('currency', 255)->nullable(); 22 | $table->string('currency_code', 255)->nullable(); 23 | $table->string('currency_sub_unit', 255)->nullable(); 24 | $table->string('currency_symbol', 3)->nullable(); 25 | $table->integer('currency_decimals')->nullable(); 26 | $table->string('full_name', 255)->nullable(); 27 | $table->string('iso_3166_2', 2)->default(''); 28 | $table->string('iso_3166_3', 3)->default(''); 29 | $table->string('name', 255)->default(''); 30 | $table->string('region_code', 3)->default(''); 31 | $table->string('sub_region_code', 3)->default(''); 32 | $table->boolean('eea')->default(0); 33 | $table->string('calling_code', 3)->nullable(); 34 | $table->string('flag', 6)->nullable(); 35 | 36 | $table->primary('id'); 37 | }); 38 | } 39 | 40 | /** 41 | * Reverse the migrations. 42 | * 43 | * @return void 44 | */ 45 | public function down() 46 | { 47 | Schema::drop(\Config::get('countries.table_name')); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /resources/views/dashboard/medicine/create.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | @section('content') 3 |
4 |
5 | @csrf 6 | 7 |
8 | 9 | 10 |
11 | @error('name') 12 |

{{ $message }}

13 | @enderror 14 | 15 |
16 | 17 | 18 | @error('type') 19 |

{{ $message }}

20 | @enderror 21 |
22 | 23 |
24 | 25 | 26 | @error('price') 27 |

{{ $message }}

28 | @enderror 29 |
30 | 31 |
32 | 33 |
34 |
35 |
36 | @endsection -------------------------------------------------------------------------------- /resources/views/vendor/scribe/partials/example-requests/bash.md.blade.php: -------------------------------------------------------------------------------- 1 | @php 2 | use Knuckles\Scribe\Tools\WritingUtils as u; 3 | /** @var Knuckles\Camel\Output\OutputEndpointData $endpoint */ 4 | @endphp 5 | ```bash 6 | curl --request {{$endpoint->httpMethods[0]}} \ 7 | {{$endpoint->httpMethods[0] == 'GET' ? '--get ' : ''}}"{{ rtrim($baseUrl, '/')}}/{{ ltrim($endpoint->boundUri, '/') }}@if(count($endpoint->cleanQueryParameters))?{!! u::printQueryParamsAsString($endpoint->cleanQueryParameters) !!}@endif"@if(count($endpoint->headers)) \ 8 | @foreach($endpoint->headers as $header => $value) 9 | --header "{{$header}}: {{ addslashes($value) }}"@if(! ($loop->last) || ($loop->last && count($endpoint->bodyParameters))) \ 10 | @endif 11 | @endforeach 12 | @endif 13 | @if($endpoint->hasFiles()) 14 | @foreach($endpoint->cleanBodyParameters as $parameter => $value) 15 | @foreach(u::getParameterNamesAndValuesForFormData($parameter, $value) as $key => $actualValue) 16 | --form "{!! "$key=".$actualValue !!}" \ 17 | @endforeach 18 | @endforeach 19 | @foreach($endpoint->fileParameters as $parameter => $value) 20 | @foreach(u::getParameterNamesAndValuesForFormData($parameter, $value) as $key => $file) 21 | --form "{!! "$key=@".$file->path() !!}" @if(!($loop->parent->last))\ 22 | @endif 23 | @endforeach 24 | @endforeach 25 | @elseif(count($endpoint->cleanBodyParameters)) 26 | @if ($endpoint->headers['Content-Type'] == 'application/x-www-form-urlencoded') 27 | --data "{!! http_build_query($endpoint->cleanBodyParameters, '', '&') !!}" 28 | @else 29 | --data "{!! addslashes(json_encode($endpoint->cleanBodyParameters, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)) !!}" 30 | @endif 31 | @endif 32 | 33 | ``` 34 | -------------------------------------------------------------------------------- /app/Http/Controllers/OrderConfirmationController.php: -------------------------------------------------------------------------------- 1 | status == 'canceled'){ 16 | Session::flash('success', 'This order has been canceled before'); 17 | return back(); 18 | } 19 | else if($order->status == 'WaitingForUserConfirmation'){ 20 | $order->status = 'confirmed'; 21 | $order->save(); 22 | return view('confirmOrder.confirmed'); 23 | } 24 | else{ 25 | Session::flash('success', 'This order has been confirmed before '); 26 | return back(); 27 | } 28 | } else { 29 | abort(404); 30 | } 31 | } 32 | public function cancelOrder($id){ 33 | $order = Order::find($id); 34 | if ($order) { 35 | if($order->status == 'WaitingForUserConfirmation'){ 36 | $order->status = 'canceled'; 37 | $order->save(); 38 | return view('confirmOrder.canceledOrder',["message"=> "canceled"]); 39 | } 40 | else { 41 | Session::flash('success', 'This order has been confirmed before you can not cancel it'); 42 | 43 | return view('confirmOrder.canceledOrder',["message"=> "can't cancel"]); 44 | 45 | } 46 | } else { 47 | abort(404); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /resources/views/dashboard/medicine/edit.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | @section('content') 3 |
4 |

Medicine

5 |
6 | @csrf 7 | @method('put') 8 |
9 | 10 | 11 | @error('name') 12 |

{{ $message }}

13 | @enderror 14 |
15 | 16 |
17 | 18 | 19 | @error('type') 20 |

{{ $message }}

21 | @enderror 22 |
23 | 24 |
25 | 26 | 27 | @error('price') 28 |

{{ $message }}

29 | @enderror 30 |
31 | 32 |
33 | 34 |
35 |
36 |
37 | @endsection -------------------------------------------------------------------------------- /.scribe/endpoints/04.yaml: -------------------------------------------------------------------------------- 1 | name: address 2 | description: '' 3 | endpoints: 4 | - 5 | httpMethods: 6 | - DELETE 7 | uri: 'api/client/{clientId}/address/{addressId}' 8 | metadata: 9 | groupName: address 10 | groupDescription: '' 11 | subgroup: '' 12 | subgroupDescription: '' 13 | title: 'Delete a specific address for a client.' 14 | description: '' 15 | authenticated: false 16 | custom: [] 17 | headers: 18 | Content-Type: application/json 19 | Accept: application/json 20 | urlParameters: 21 | clientId: 22 | name: clientId 23 | description: 'The ID of the client who owns the address.' 24 | required: true 25 | example: autem 26 | type: string 27 | custom: [] 28 | addressId: 29 | name: addressId 30 | description: 'The ID of the address to be deleted.' 31 | required: true 32 | example: quasi 33 | type: string 34 | custom: [] 35 | cleanUrlParameters: 36 | clientId: autem 37 | addressId: quasi 38 | queryParameters: [] 39 | cleanQueryParameters: [] 40 | bodyParameters: [] 41 | cleanBodyParameters: [] 42 | fileParameters: [] 43 | responses: 44 | - 45 | status: 200 46 | content: |- 47 | { 48 | "message": "Address deleted successfully" 49 | } 50 | headers: [] 51 | description: '' 52 | custom: [] 53 | - 54 | status: 404 55 | content: |- 56 | { 57 | "message": "Address not found" 58 | } 59 | headers: [] 60 | description: '' 61 | custom: [] 62 | responseFields: [] 63 | auth: [] 64 | controller: null 65 | method: null 66 | route: null 67 | custom: [] 68 | -------------------------------------------------------------------------------- /public/js/darkmode.js: -------------------------------------------------------------------------------- 1 | 2 | let darkmodebtn = document.querySelector("#dark-mode"); 3 | let body = document.querySelector('body'); 4 | let nav = document.querySelector('nav'); 5 | let navLinkText = document.querySelector(".nav-link-text"); 6 | let i = document.querySelector('i'); 7 | let footer = document.querySelector('footer'); 8 | let aside = document.querySelector('aside'); 9 | let chartWrapper = document.querySelector(".chartWrapper"); 10 | let html = document.querySelector('html'); 11 | 12 | 13 | const savedValue = localStorage.getItem("site-mode"); 14 | if (savedValue !== null) { 15 | darkmodebtn.checked = savedValue === "dark"; 16 | if(darkmodebtn.checked){ 17 | body.classList.add("darkMode") 18 | footer.classList.add("bg-gradient-dark"); 19 | html.style.backgroundColor = "black !important"; 20 | } 21 | else{ 22 | body.classList.add("lightMode"); 23 | footer.classList.remove("bg-gradient-dark"); 24 | footer.style.backgroundColor = "rgba(0,0,0,0.5)"; 25 | nav.style.backgroundColor = "rgba(0,0,0,0.5)"; 26 | // html.style.backgroundColor = "black !important"; 27 | } 28 | } 29 | 30 | darkmodebtn.addEventListener('change', function(){ 31 | const value = this.checked ? "dark" : "light"; 32 | 33 | if (darkmodebtn.checked) { 34 | body.classList.remove("bg-gray-200"); 35 | body.classList.remove("lightMode"); 36 | body.classList.add("darkMode"); 37 | navLinkText.style.color ='white'; 38 | footer.classList.add("bg-gradient-dark"); 39 | } else { 40 | body.classList.remove("bg-gray-200"); 41 | body.classList.remove("darkMode"); 42 | body.classList.add("lightMode"); 43 | footer.classList.remove('bg-gradient-dark'); 44 | } 45 | 46 | localStorage.setItem("site-mode", value); 47 | }) 48 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /resources/views/confirmOrder/confirmed.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 10 | 11 | 12 | 13 |
14 | 15 |
16 |
17 |
18 |
19 |
20 |
21 | email picture 22 |
23 |
24 |
25 |
26 |

order Confirmed

27 |

We are pleased to inform you that your order has been confirmed and is on its way to you.

28 |

Thank you for choosing DrugRadar. We hope to serve you again in the future.

29 |
30 |
31 |
32 |
33 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /.scribe/endpoints.cache/04.yaml: -------------------------------------------------------------------------------- 1 | ## Autogenerated by Scribe. DO NOT MODIFY. 2 | 3 | name: address 4 | description: '' 5 | endpoints: 6 | - 7 | httpMethods: 8 | - DELETE 9 | uri: 'api/client/{clientId}/address/{addressId}' 10 | metadata: 11 | groupName: address 12 | groupDescription: '' 13 | subgroup: '' 14 | subgroupDescription: '' 15 | title: 'Delete a specific address for a client.' 16 | description: '' 17 | authenticated: false 18 | custom: [] 19 | headers: 20 | Content-Type: application/json 21 | Accept: application/json 22 | urlParameters: 23 | clientId: 24 | name: clientId 25 | description: 'The ID of the client who owns the address.' 26 | required: true 27 | example: autem 28 | type: string 29 | custom: [] 30 | addressId: 31 | name: addressId 32 | description: 'The ID of the address to be deleted.' 33 | required: true 34 | example: quasi 35 | type: string 36 | custom: [] 37 | cleanUrlParameters: 38 | clientId: autem 39 | addressId: quasi 40 | queryParameters: [] 41 | cleanQueryParameters: [] 42 | bodyParameters: [] 43 | cleanBodyParameters: [] 44 | fileParameters: [] 45 | responses: 46 | - 47 | status: 200 48 | content: |- 49 | { 50 | "message": "Address deleted successfully" 51 | } 52 | headers: [] 53 | description: '' 54 | custom: [] 55 | - 56 | status: 404 57 | content: |- 58 | { 59 | "message": "Address not found" 60 | } 61 | headers: [] 62 | description: '' 63 | custom: [] 64 | responseFields: [] 65 | auth: [] 66 | controller: null 67 | method: null 68 | route: null 69 | custom: [] 70 | -------------------------------------------------------------------------------- /artisan: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | make(Illuminate\Contracts\Console\Kernel::class); 34 | 35 | $status = $kernel->handle( 36 | $input = new Symfony\Component\Console\Input\ArgvInput, 37 | new Symfony\Component\Console\Output\ConsoleOutput 38 | ); 39 | 40 | /* 41 | |-------------------------------------------------------------------------- 42 | | Shutdown The Application 43 | |-------------------------------------------------------------------------- 44 | | 45 | | Once Artisan has finished running, we will fire off the shutdown events 46 | | so that any final work may be done by the application before we shut 47 | | down the process. This is the last thing to happen to the request. 48 | | 49 | */ 50 | 51 | $kernel->terminate($input, $status); 52 | 53 | exit($status); 54 | -------------------------------------------------------------------------------- /resources/views/vendor/scribe/partials/example-requests/python.md.blade.php: -------------------------------------------------------------------------------- 1 | @php 2 | use Knuckles\Scribe\Tools\WritingUtils as u; 3 | /** @var Knuckles\Camel\Output\OutputEndpointData $endpoint */ 4 | @endphp 5 | ```python 6 | import requests 7 | import json 8 | 9 | url = '{{ rtrim($baseUrl, '/') }}/{{ $endpoint->boundUri }}' 10 | @if($endpoint->hasFiles()) 11 | files = { 12 | @foreach($endpoint->fileParameters as $parameter => $value) 13 | @foreach(u::getParameterNamesAndValuesForFormData($parameter, $value) as $key => $file) 14 | '{!! $key !!}': open('{!! $file->path() !!}', 'rb')@if(!($loop->parent->last)), 15 | @endif 16 | @endforeach 17 | @endforeach 18 | 19 | } 20 | @endif 21 | @if(count($endpoint->cleanBodyParameters)) 22 | payload = {!! json_encode($endpoint->cleanBodyParameters, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) !!} 23 | @endif 24 | @if(count($endpoint->cleanQueryParameters)) 25 | params = {!! u::printQueryParamsAsKeyValue($endpoint->cleanQueryParameters, "'", ":", 2, "{}") !!} 26 | @endif 27 | @if(!empty($endpoint->headers)) 28 | headers = { 29 | @foreach($endpoint->headers as $header => $value) 30 | '{{$header}}': '{{$value}}'@if(!($loop->last)), 31 | @endif 32 | @endforeach 33 | 34 | } 35 | 36 | @endif 37 | @php 38 | $optionalArguments = []; 39 | if (count($endpoint->headers)) $optionalArguments[] = "headers=headers"; 40 | if (count($endpoint->fileParameters)) $optionalArguments[] = "files=files"; 41 | if (count($endpoint->cleanBodyParameters)) $optionalArguments[] = (count($endpoint->fileParameters) || $endpoint->headers['Content-Type'] == 'application/x-www-form-urlencoded' ? "data=payload" : "json=payload"); 42 | if (count($endpoint->cleanQueryParameters)) $optionalArguments[] = "params=params"; 43 | $optionalArguments = implode(', ',$optionalArguments); 44 | @endphp 45 | response = requests.request('{{$endpoint->httpMethods[0]}}', url, {{ $optionalArguments }}) 46 | response.json() 47 | ``` 48 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /app/Http/Requests/UpdateDoctorRequest.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | public function rules(): array 26 | { 27 | return [ 28 | 'name' => ['required', "max:255"], 29 | 'email' => ['required', "max:255",'email', Rule::unique('users')->ignore($this->getDoctorIdInUser())], 30 | 'password' => ['required', "max:255",'min:6'], 31 | 'national_id' => ['required','integer','digits:14', Rule::unique('doctors')->ignore(Auth::user()->roles[0]->name=='doctor' ? $this->id :$this->doctor)], 32 | 'avatar_image' => ['image', "max:255",'mimes:jpeg,jpg,png'], 33 | 'pharmacy_id' => ["required", "exists:pharmacies,id"], 34 | ]; 35 | } 36 | 37 | public function messages() 38 | { 39 | return [ 40 | 'pharmacy_id.exists' => "This pharmacy is invalid.", 41 | 'pharmacy_id.required' => "The pharmacy is required.", 42 | ]; 43 | } 44 | 45 | public function getDoctorIdInUser() { 46 | if(Auth::user()->roles[0]->name=='doctor'){ 47 | $id = $this->id ; 48 | } 49 | else{ 50 | $id = $this -> doctor ; 51 | } 52 | $user = User::where('userable_id', $id) 53 | ->where('userable_type', 'App\Models\Doctor') 54 | ->get(); 55 | return $user->first()->id; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /.scribe/endpoints/custom.0.yaml: -------------------------------------------------------------------------------- 1 | # To include an endpoint that isn't a part of your Laravel app (or belongs to a vendor package), 2 | # you can define it in a custom.*.yaml file, like this one. 3 | # Each custom file should contain an array of endpoints. Here's an example: 4 | # See https://scribe.knuckles.wtf/laravel/documenting/custom-endpoints#extra-sorting-groups-in-custom-endpoint-files for more options 5 | 6 | #- httpMethods: 7 | # - POST 8 | # uri: api/doSomething/{param} 9 | # metadata: 10 | # groupName: The group the endpoint belongs to. Can be a new group or an existing group. 11 | # groupDescription: A description for the group. You don't need to set this for every endpoint; once is enough. 12 | # subgroup: You can add a subgroup, too. 13 | # title: Do something 14 | # description: 'This endpoint allows you to do something.' 15 | # authenticated: false 16 | # headers: 17 | # Content-Type: application/json 18 | # Accept: application/json 19 | # urlParameters: 20 | # param: 21 | # name: param 22 | # description: A URL param for no reason. 23 | # required: true 24 | # example: 2 25 | # type: integer 26 | # queryParameters: 27 | # speed: 28 | # name: speed 29 | # description: How fast the thing should be done. Can be `slow` or `fast`. 30 | # required: false 31 | # example: fast 32 | # type: string 33 | # bodyParameters: 34 | # something: 35 | # name: something 36 | # description: The things we should do. 37 | # required: true 38 | # example: 39 | # - string 1 40 | # - string 2 41 | # type: 'string[]' 42 | # responses: 43 | # - status: 200 44 | # description: 'When the thing was done smoothly.' 45 | # content: # Your response content can be an object, an array, a string or empty. 46 | # { 47 | # "hey": "ho ho ho" 48 | # } 49 | # responseFields: 50 | # hey: 51 | # name: hey 52 | # description: Who knows? 53 | # type: string # This is optional 54 | -------------------------------------------------------------------------------- /app/Http/Requests/UpdatePharmacyRequest.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | public function rules() 26 | { 27 | return [ 28 | 'name' => ['required', "max:255"], 29 | 'email' => ['required', "max:255", 'email', Rule::unique('users')->ignore($this->getPharmacyIdInUser())], 30 | 'password' => ['required', "max:255",'min:6'], 31 | 'national_id' => ['required','integer','digits:14', Rule::unique('pharmacies')->ignore(Auth::user()->roles[0]->name=='pharmacy' ? $this->id : $this->pharmacy)], 32 | 'avatar_image' => ['image',"max:255",'mimes:jpeg,jpg,png'], 33 | 'area_id' => ["required", "exists:areas,id"], 34 | 'priority' => ['required', 'integer', 'min:0'], 35 | 36 | ]; 37 | } 38 | 39 | public function messages() 40 | { 41 | return [ 42 | 'area_id.exists' => "This area is invalid.", 43 | 'area_id.required' => "The area is required." 44 | ]; 45 | } 46 | 47 | public function getPharmacyIdInUser() { 48 | // dd($this->id); 49 | if(Auth::user()->roles[0]->name=='pharmacy'){ 50 | $id = $this->id ; 51 | } 52 | else{ 53 | $id = $this -> pharmacy ; 54 | } 55 | $user = User::where('userable_id', $id) 56 | ->where('userable_type', 'App\Models\Pharmacy') 57 | ->get(); 58 | return $user->first()->id; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /resources/views/dashboard/area/create.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | @section('content') 3 |
4 |

Areas

5 |
6 | @csrf 7 | 8 |
9 | 10 | 11 | @error('name') 12 |

{{ $message }}

13 | @enderror 14 |
15 | 16 |
17 | 18 | 19 | @error('address') 20 |

{{ $message }}

21 | @enderror 22 |
23 | 24 |
25 | 26 | 31 | @error('country_id') 32 |

{{ $message }}

33 | @enderror 34 |
35 | 36 |
37 | 38 |
39 |
40 |
41 | @endsection 42 | 43 | @section('scripts') 44 | 49 | @endsection 50 | -------------------------------------------------------------------------------- /resources/views/dashboard/area/edit.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | @section('content') 3 |
4 |

Areas

5 |
6 | @csrf 7 | @method('put') 8 |
9 | 10 | 11 | @error('name') 12 |

{{ $message }}

13 | @enderror 14 |
15 | 16 |
17 | 18 | 19 | @error('address') 20 |

{{ $message }}

21 | @enderror 22 |
23 | 24 |
25 | 26 | 31 | @error('country_id') 32 |

{{ $message }}

33 | @enderror 34 |
35 | 36 |
37 | 38 |
39 |
40 |
41 | @endsection 42 | 43 | @section('scripts') 44 | 49 | @endsection -------------------------------------------------------------------------------- /resources/views/vendor/scribe/partials/example-requests/php.md.blade.php: -------------------------------------------------------------------------------- 1 | @php 2 | use Knuckles\Scribe\Tools\WritingUtils as u; 3 | /** @var Knuckles\Camel\Output\OutputEndpointData $endpoint */ 4 | @endphp 5 | ```php 6 | $client = new \GuzzleHttp\Client(); 7 | @if($endpoint->hasHeadersOrQueryOrBodyParams()) 8 | $response = $client->{{ strtolower($endpoint->httpMethods[0]) }}( 9 | '{{ rtrim($baseUrl, '/') . '/' . ltrim($endpoint->boundUri, '/') }}', 10 | [ 11 | @if(!empty($endpoint->headers)) 12 | 'headers' => {!! u::printPhpValue($endpoint->headers, 8) !!}, 13 | @endif 14 | @if(!empty($endpoint->cleanQueryParameters)) 15 | 'query' => {!! u::printQueryParamsAsKeyValue($endpoint->cleanQueryParameters, "'", " =>", 12, "[]", 8) !!}, 16 | @endif 17 | @if($endpoint->hasFiles()) 18 | 'multipart' => [ 19 | @foreach($endpoint->cleanBodyParameters as $parameter => $value) 20 | @foreach(u::getParameterNamesAndValuesForFormData($parameter, $value) as $key => $actualValue) 21 | [ 22 | 'name' => '{!! $key !!}', 23 | 'contents' => '{!! $actualValue !!}' 24 | ], 25 | @endforeach 26 | @endforeach 27 | @foreach($endpoint->fileParameters as $parameter => $value) 28 | @foreach(u::getParameterNamesAndValuesForFormData($parameter, $value) as $key => $file) 29 | [ 30 | 'name' => '{!! $key !!}', 31 | 'contents' => fopen('{!! $file->path() !!}', 'r') 32 | ], 33 | @endforeach 34 | @endforeach 35 | ], 36 | @elseif(!empty($endpoint->cleanBodyParameters)) 37 | @if ($endpoint->headers['Content-Type'] == 'application/x-www-form-urlencoded') 38 | 'form_params' => {!! u::printPhpValue($endpoint->cleanBodyParameters, 8) !!}, 39 | @else 40 | 'json' => {!! u::printPhpValue($endpoint->cleanBodyParameters, 8) !!}, 41 | @endif 42 | @endif 43 | ] 44 | ); 45 | @else 46 | $response = $client->{{ strtolower($endpoint->httpMethods[0]) }}('{{ rtrim($baseUrl, '/') . '/' . ltrim($endpoint->boundUri, '/') }}'); 47 | @endif 48 | $body = $response->getBody(); 49 | print_r(json_decode((string) $body)); 50 | ``` 51 | -------------------------------------------------------------------------------- /resources/views/confirmOrder/canceledOrder.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 10 | 11 | 12 | 13 |
14 | 15 |
16 |
17 |
18 |
19 |
20 |
21 | email picture 22 |
23 |
24 |
25 | @if($message == 'canceled') 26 |
27 |

Order Cancelled

28 |

We're sorry to hear that you've cancelled your order

29 |

Thank you for choosing DrugRadar. We hope to serve you again in the future.

30 |
31 | @else 32 |
33 |

Order Can't be canceled

34 |

We're sorry but you can not cancel this order

35 |

Thank you for choosing DrugRadar. We hope to serve you again in the future.

36 |
37 | @endif 38 |
39 |
40 |
41 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /database/seeders/CountriesSeeder.php: -------------------------------------------------------------------------------- 1 | delete(); 23 | 24 | //Get all of the countries 25 | $countries = (new Countries())->getList(); 26 | foreach ($countries as $countryId => $country){ 27 | DB::table(\Config::get('countries.table_name'))->insert(array( 28 | 'id' => $countryId, 29 | 'capital' => ((isset($country['capital'])) ? $country['capital'] : null), 30 | 'citizenship' => ((isset($country['citizenship'])) ? $country['citizenship'] : null), 31 | 'country_code' => $country['country-code'], 32 | 'currency' => ((isset($country['currency'])) ? $country['currency'] : null), 33 | 'currency_code' => ((isset($country['currency_code'])) ? $country['currency_code'] : null), 34 | 'currency_sub_unit' => ((isset($country['currency_sub_unit'])) ? $country['currency_sub_unit'] : null), 35 | 'currency_decimals' => ((isset($country['currency_decimals'])) ? $country['currency_decimals'] : null), 36 | 'full_name' => ((isset($country['full_name'])) ? $country['full_name'] : null), 37 | 'iso_3166_2' => $country['iso_3166_2'], 38 | 'iso_3166_3' => $country['iso_3166_3'], 39 | 'name' => $country['name'], 40 | 'region_code' => $country['region-code'], 41 | 'sub_region_code' => $country['sub-region-code'], 42 | 'eea' => (bool)$country['eea'], 43 | 'calling_code' => $country['calling_code'], 44 | 'currency_symbol' => ((isset($country['currency_symbol'])) ? $country['currency_symbol'] : null), 45 | 'flag' =>((isset($country['flag'])) ? $country['flag'] : null), 46 | )); 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/RevenueController.php: -------------------------------------------------------------------------------- 1 | roles[0]->name=='admin') { 15 | if ($request->ajax()) { 16 | $data = Pharmacy::latest()->get(); 17 | return DataTables::of($data) 18 | ->addIndexColumn() 19 | ->addColumn('avatar_image_url', function ($row) { 20 | return $row->getFirstMediaUrl('avatar_image', 'thumb') ? $row->getFirstMediaUrl('avatar_image', 'thumb') : asset('assets/gifs/user.png'); 21 | }) 22 | ->addColumn('totalOrders', function (Pharmacy $pharmacy) { 23 | $ordersCount = DB::table('orders')->where('assigned_pharmacy_id', $pharmacy->id)->count(); 24 | return $ordersCount; 25 | }) 26 | ->addColumn('totalRevenue', function (Pharmacy $pharmacy) { 27 | $ordersRevenue = DB::table('orders')->where('assigned_pharmacy_id', $pharmacy->id) 28 | ->where('status', 'delivered') 29 | ->sum('total_price'); 30 | return $ordersRevenue; 31 | }) 32 | ->make(true); 33 | 34 | } 35 | return view('dashboard.revenue.index'); 36 | }else if(Auth::user()->roles[0]->name == 'pharmacy'){ 37 | $pharmacy_id = Auth::user()->userable_id; 38 | $PharmacyRevenue = DB::table('orders')->where('assigned_pharmacy_id',$pharmacy_id) 39 | ->sum('total_price'); 40 | $pharmacy = Pharmacy::find(Auth::user()->userable_id); 41 | $pharmacyName = $pharmacy->name; 42 | return view('dashboard.revenue.PharmacyRevenue',['pharmacy_revenue'=>$PharmacyRevenue,'pharmacyName'=>$pharmacyName]); 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /resources/views/vendor/scribe/partials/example-requests/javascript.md.blade.php: -------------------------------------------------------------------------------- 1 | @php 2 | use Knuckles\Scribe\Tools\WritingUtils as u; 3 | /** @var Knuckles\Camel\Output\OutputEndpointData $endpoint */ 4 | @endphp 5 | ```javascript 6 | const url = new URL( 7 | "{{ rtrim($baseUrl, '/') }}/{{ ltrim($endpoint->boundUri, '/') }}" 8 | ); 9 | @if(count($endpoint->cleanQueryParameters)) 10 | 11 | const params = {!! u::printQueryParamsAsKeyValue($endpoint->cleanQueryParameters, "\"", ":", 4, "{}") !!}; 12 | Object.keys(params) 13 | .forEach(key => url.searchParams.append(key, params[key])); 14 | @endif 15 | 16 | @if(!empty($endpoint->headers)) 17 | const headers = { 18 | @foreach($endpoint->headers as $header => $value) 19 | "{{$header}}": "{{$value}}", 20 | @endforeach 21 | @empty($endpoint->headers['Accept']) 22 | "Accept": "application/json", 23 | @endempty 24 | }; 25 | @endif 26 | 27 | @if($endpoint->hasFiles()) 28 | const body = new FormData(); 29 | @foreach($endpoint->cleanBodyParameters as $parameter => $value) 30 | @foreach( u::getParameterNamesAndValuesForFormData($parameter, $value) as $key => $actualValue) 31 | body.append('{!! $key !!}', '{!! $actualValue !!}'); 32 | @endforeach 33 | @endforeach 34 | @foreach($endpoint->fileParameters as $parameter => $value) 35 | @foreach( u::getParameterNamesAndValuesForFormData($parameter, $value) as $key => $file) 36 | body.append('{!! $key !!}', document.querySelector('input[name="{!! $key !!}"]').files[0]); 37 | @endforeach 38 | @endforeach 39 | @elseif(count($endpoint->cleanBodyParameters)) 40 | @if ($endpoint->headers['Content-Type'] == 'application/x-www-form-urlencoded') 41 | let body = "{!! http_build_query($endpoint->cleanBodyParameters, '', '&') !!}"; 42 | @else 43 | let body = {!! json_encode($endpoint->cleanBodyParameters, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) !!}; 44 | @endif 45 | @endif 46 | 47 | fetch(url, { 48 | method: "{{$endpoint->httpMethods[0]}}", 49 | @if(count($endpoint->headers)) 50 | headers, 51 | @endif 52 | @if($endpoint->hasFiles()) 53 | body, 54 | @elseif(count($endpoint->cleanBodyParameters)) 55 | @if ($endpoint->headers['Content-Type'] == 'application/x-www-form-urlencoded') 56 | body: body, 57 | @else 58 | body: JSON.stringify(body), 59 | @endif 60 | @endif 61 | }).then(response => response.json()); 62 | ``` 63 | -------------------------------------------------------------------------------- /resources/views/dashboard/revenue/index.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | @section('content') 3 | 4 |

Revenue

5 |
6 |
7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
Pharmacy AvatarPharmacy NameTotal OrdersTotal Revenue
21 | @endsection 22 | @section('scripts') 23 | 72 | @endsection -------------------------------------------------------------------------------- /app/Http/Controllers/ClientController.php: -------------------------------------------------------------------------------- 1 | all(); 17 | $client = new Client(); 18 | $client->fill($data); 19 | $client->save(); 20 | $options = stream_context_create([ 21 | 'ssl' => [ 22 | 'verify_peer' => false, 23 | 'verify_peer_name' => false, 24 | ], 25 | ]); 26 | if ($client instanceof MustVerifyEmail && ! $client->hasVerifiedEmail()) { 27 | event(new Registered($client)); 28 | } 29 | return response()->json([ 30 | 'message' => 'Client created successfully', 31 | 'data' => $client 32 | ], 201); 33 | } 34 | 35 | public function verify(Request $request, $id, $hash) 36 | { 37 | $client = Client::findOrFail($id); 38 | 39 | if (! hash_equals((string) $hash, sha1($client->getEmailForVerification()))) { 40 | throw new AuthorizationException(); 41 | } 42 | 43 | $client->markEmailAsVerified(); 44 | $client->save(); 45 | 46 | return response()->json([ 47 | 'message' => 'Email verified successfully' 48 | ]); 49 | } 50 | 51 | public function login(Request $request) 52 | { 53 | $email = $request->input('email'); 54 | $password = $request->input('password'); 55 | 56 | $user = Client::where('email', $email) 57 | ->where('password', $password) 58 | ->first(); 59 | 60 | if ($user) { 61 | return response()->json([ 62 | 'message' => 'Client logged in successfully', 63 | 'data' => $user 64 | ], 201); 65 | } else { 66 | return response()->json([ 67 | 'message' => 'Error in login. Password or name are incorrect.', 68 | 'data' => null 69 | ], 404); 70 | } 71 | } 72 | } -------------------------------------------------------------------------------- /database/migrations/2023_04_03_153549_charify_countries_table.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 | 'host' => env('PUSHER_HOST') ?: 'api-'.env('PUSHER_APP_CLUSTER', 'mt1').'.pusher.com', 40 | 'port' => env('PUSHER_PORT', 443), 41 | 'scheme' => env('PUSHER_SCHEME', 'https'), 42 | 'encrypted' => true, 43 | 'useTLS' => env('PUSHER_SCHEME', 'https') === 'https', 44 | ], 45 | 'client_options' => [ 46 | // Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html 47 | ], 48 | ], 49 | 50 | 'ably' => [ 51 | 'driver' => 'ably', 52 | 'key' => env('ABLY_KEY'), 53 | ], 54 | 55 | 'redis' => [ 56 | 'driver' => 'redis', 57 | 'connection' => 'default', 58 | ], 59 | 60 | 'log' => [ 61 | 'driver' => 'log', 62 | ], 63 | 64 | 'null' => [ 65 | 'driver' => 'null', 66 | ], 67 | 68 | ], 69 | 70 | ]; 71 | -------------------------------------------------------------------------------- /app/Http/Controllers/ChartController.php: -------------------------------------------------------------------------------- 1 | year; 23 | if (Auth::user()->roles[0]->name == 'admin') { 24 | $revenueData = Order::selectRaw('MONTH(created_at) as month, SUM(total_price) as revenue') 25 | ->whereYear('created_at', $currentYear) 26 | ->groupBy('month') 27 | ->orderBy('month') 28 | ->get(); 29 | } 30 | else if(Auth::user()->roles[0]->name == 'pharmacy'){ 31 | $revenueData = Order::selectRaw('MONTH(created_at) as month, SUM(total_price) as revenue') 32 | ->where('assigned_pharmacy_id',Auth::user()->userable_id ) 33 | ->whereYear('created_at', $currentYear) 34 | ->groupBy('month') 35 | ->orderBy('month') 36 | ->get(); 37 | } 38 | return response()->json(['data' => $revenueData]); 39 | } 40 | 41 | public function genderAttendance() 42 | { 43 | $males = Client::where('gender', 'male')->count(); 44 | $females = Client::where('gender', 'female')->count(); 45 | return response()->json([ 46 | 'labels' => ['Males', 'Females'], 47 | 'datasets' => [ 48 | [ 49 | 'data' => [$males, $females], 50 | 'backgroundColor' => ['#36a2eb', '#ff6384'] 51 | ] 52 | ] 53 | ]); 54 | } 55 | 56 | public function topUsers() 57 | { 58 | try { 59 | $data = DB::table('orders') 60 | ->join('clients', 'orders.client_id', '=', 'clients.id') 61 | ->select('clients.name', DB::raw('COUNT(orders.id) as orders_count')) 62 | ->groupBy('clients.id', 'clients.name') 63 | ->orderByDesc('orders_count') 64 | ->limit(10) 65 | ->get(); 66 | 67 | return response()->json(['data' => $data]); 68 | } catch (\Exception $e) { 69 | return response()->json(['error' => $e->getMessage()]); 70 | } 71 | } 72 | 73 | } -------------------------------------------------------------------------------- /resources/views/dashboard/order/medicinesOrder.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | @section('content') 3 |
4 |
5 | @csrf 6 |
7 |

Medicine Name

8 |

Medicine Price

9 |

Medicine Quantity

10 |

Medicine Type

11 |
12 | @foreach($medicines as $index => $medicine ) 13 |
14 |
15 | 16 | 17 | 18 | 19 |
20 |
21 | @endforeach 22 | 23 | 24 |
25 | 26 | 27 |
28 | 29 | @endsection 30 | @section('scripts') 31 | 58 | @endsection -------------------------------------------------------------------------------- /resources/views/dashboard/admin/profile.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | @section('content') 3 | 66 | 67 |
68 | profile picture 69 |
70 |

Name

71 |

{{$admin->name}}

72 |
73 |
74 |
75 |
76 |
77 |
Email
78 |

{{$admin->email}}

79 |
80 |
81 |
82 |
83 |
84 |
85 |
Member since
86 |

{{$admin->created_at->longRelativeToNowDiffForHumans()}}

87 |
88 |
89 |
90 | 91 | @endsection -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "laravel/laravel", 3 | "type": "project", 4 | "description": "The Laravel Framework.", 5 | "keywords": [ 6 | "framework", 7 | "laravel" 8 | ], 9 | "license": "MIT", 10 | "require": { 11 | "php": "^8.1", 12 | "cybercog/laravel-ban": "^4.8", 13 | "guzzlehttp/guzzle": "^7.2", 14 | "laravel/framework": "^10.0", 15 | "laravel/sanctum": "^3.2", 16 | "laravel/tinker": "^2.8", 17 | "laravel/ui": "^4.2", 18 | "maatwebsite/excel": "^3.1", 19 | "psr/simple-cache": "1.0", 20 | "spatie/laravel-medialibrary": "^10.7", 21 | "spatie/laravel-permission": "^5.10", 22 | "stripe/stripe-php": "^10.12", 23 | "webpatser/laravel-countries": "dev-master", 24 | "yajra/laravel-datatables-oracle": "^10.4" 25 | }, 26 | "require-dev": { 27 | "fakerphp/faker": "^1.9.1", 28 | "knuckleswtf/scribe": "^4.17", 29 | "laravel/pint": "^1.0", 30 | "laravel/sail": "^1.18", 31 | "mockery/mockery": "^1.4.4", 32 | "nunomaduro/collision": "^7.0", 33 | "phpunit/phpunit": "^10.0", 34 | "spatie/laravel-ignition": "^2.0" 35 | }, 36 | "autoload": { 37 | "psr-4": { 38 | "App\\": "app/", 39 | "Database\\Factories\\": "database/factories/", 40 | "Database\\Seeders\\": "database/seeders/" 41 | } 42 | }, 43 | "autoload-dev": { 44 | "psr-4": { 45 | "Tests\\": "tests/" 46 | } 47 | }, 48 | "scripts": { 49 | "post-autoload-dump": [ 50 | "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump", 51 | "@php artisan package:discover --ansi" 52 | ], 53 | "post-update-cmd": [ 54 | "@php artisan vendor:publish --tag=laravel-assets --ansi --force" 55 | ], 56 | "post-root-package-install": [ 57 | "@php -r \"file_exists('.env') || copy('.env.example', '.env');\"" 58 | ], 59 | "post-create-project-cmd": [ 60 | "@php artisan key:generate --ansi" 61 | ] 62 | }, 63 | "extra": { 64 | "laravel": { 65 | "dont-discover": [] 66 | } 67 | }, 68 | "config": { 69 | "optimize-autoloader": true, 70 | "preferred-install": "dist", 71 | "sort-packages": true, 72 | "allow-plugins": { 73 | "pestphp/pest-plugin": true, 74 | "php-http/discovery": true 75 | } 76 | }, 77 | "minimum-stability": "stable", 78 | "prefer-stable": true 79 | } 80 | --------------------------------------------------------------------------------