├── Book-reviews-project ├── README.md ├── app │ ├── Console │ │ └── Kernel.php │ ├── Exceptions │ │ └── Handler.php │ ├── Http │ │ ├── Controllers │ │ │ ├── BookController.php │ │ │ ├── Controller.php │ │ │ └── ReviewController.php │ │ ├── Kernel.php │ │ └── Middleware │ │ │ ├── Authenticate.php │ │ │ ├── EncryptCookies.php │ │ │ ├── PreventRequestsDuringMaintenance.php │ │ │ ├── RedirectIfAuthenticated.php │ │ │ ├── TrimStrings.php │ │ │ ├── TrustHosts.php │ │ │ ├── TrustProxies.php │ │ │ ├── ValidateSignature.php │ │ │ └── VerifyCsrfToken.php │ ├── Models │ │ ├── Book.php │ │ ├── Review.php │ │ └── User.php │ ├── Providers │ │ ├── AppServiceProvider.php │ │ ├── AuthServiceProvider.php │ │ ├── BroadcastServiceProvider.php │ │ ├── EventServiceProvider.php │ │ └── RouteServiceProvider.php │ └── View │ │ └── Components │ │ └── StarRating.php ├── artisan ├── bootstrap │ ├── app.php │ └── cache │ │ └── .gitignore ├── composer.json ├── composer.lock ├── config │ ├── app.php │ ├── auth.php │ ├── broadcasting.php │ ├── cache.php │ ├── cors.php │ ├── database.php │ ├── filesystems.php │ ├── hashing.php │ ├── logging.php │ ├── mail.php │ ├── queue.php │ ├── sanctum.php │ ├── services.php │ ├── session.php │ └── view.php ├── database │ ├── .gitignore │ ├── factories │ │ ├── BookFactory.php │ │ ├── ReviewFactory.php │ │ └── UserFactory.php │ ├── migrations │ │ ├── 2014_10_12_000000_create_users_table.php │ │ ├── 2014_10_12_100000_create_password_reset_tokens_table.php │ │ ├── 2019_08_19_000000_create_failed_jobs_table.php │ │ ├── 2019_12_14_000001_create_personal_access_tokens_table.php │ │ ├── 2023_08_24_114736_create_books_table.php │ │ └── 2023_08_24_114750_create_reviews_table.php │ └── seeders │ │ └── DatabaseSeeder.php ├── package.json ├── phpunit.xml ├── public │ ├── .htaccess │ ├── favicon.ico │ ├── index.php │ └── robots.txt ├── resources │ ├── css │ │ └── app.css │ ├── js │ │ ├── app.js │ │ └── bootstrap.js │ └── views │ │ ├── books │ │ ├── index.blade.php │ │ ├── reviews │ │ │ └── create.blade.php │ │ └── show.blade.php │ │ ├── components │ │ └── star-rating.blade.php │ │ ├── layouts │ │ └── app.blade.php │ │ └── welcome.blade.php ├── routes │ ├── api.php │ ├── channels.php │ ├── console.php │ └── web.php ├── storage │ ├── app │ │ ├── .gitignore │ │ └── public │ │ │ └── .gitignore │ ├── framework │ │ ├── .gitignore │ │ ├── cache │ │ │ ├── .gitignore │ │ │ └── data │ │ │ │ └── .gitignore │ │ ├── sessions │ │ │ └── .gitignore │ │ ├── testing │ │ │ └── .gitignore │ │ └── views │ │ │ └── .gitignore │ └── logs │ │ └── .gitignore ├── tests │ ├── CreatesApplication.php │ ├── Feature │ │ └── ExampleTest.php │ ├── TestCase.php │ └── Unit │ │ └── ExampleTest.php └── vite.config.js ├── event-management ├── .editorconfig ├── .env.example ├── .gitattributes ├── .gitignore ├── README.md ├── app │ ├── Console │ │ ├── Commands │ │ │ └── SendEventReminders.php │ │ └── Kernel.php │ ├── Exceptions │ │ └── Handler.php │ ├── Http │ │ ├── Controllers │ │ │ ├── Api │ │ │ │ ├── AttendeeController.php │ │ │ │ ├── AuthController.php │ │ │ │ └── EventController.php │ │ │ └── Controller.php │ │ ├── Kernel.php │ │ ├── Middleware │ │ │ ├── Authenticate.php │ │ │ ├── EncryptCookies.php │ │ │ ├── PreventRequestsDuringMaintenance.php │ │ │ ├── RedirectIfAuthenticated.php │ │ │ ├── TrimStrings.php │ │ │ ├── TrustHosts.php │ │ │ ├── TrustProxies.php │ │ │ ├── ValidateSignature.php │ │ │ └── VerifyCsrfToken.php │ │ ├── Resources │ │ │ ├── AttendeeResource.php │ │ │ ├── EventResource.php │ │ │ └── UserResource.php │ │ └── Traits │ │ │ └── CanLoadRelationships.php │ ├── Models │ │ ├── Attendee.php │ │ ├── Event.php │ │ └── User.php │ ├── Notifications │ │ └── EventReminderNotification.php │ ├── Policies │ │ ├── AttendeePolicy.php │ │ └── EventPolicy.php │ └── Providers │ │ ├── AppServiceProvider.php │ │ ├── AuthServiceProvider.php │ │ ├── BroadcastServiceProvider.php │ │ ├── EventServiceProvider.php │ │ └── RouteServiceProvider.php ├── artisan ├── bootstrap │ ├── app.php │ └── cache │ │ └── .gitignore ├── composer.json ├── composer.lock ├── config │ ├── app.php │ ├── auth.php │ ├── broadcasting.php │ ├── cache.php │ ├── cors.php │ ├── database.php │ ├── filesystems.php │ ├── hashing.php │ ├── logging.php │ ├── mail.php │ ├── queue.php │ ├── sanctum.php │ ├── services.php │ ├── session.php │ └── view.php ├── database │ ├── .gitignore │ ├── factories │ │ ├── EventFactory.php │ │ └── UserFactory.php │ ├── migrations │ │ ├── 2014_10_12_000000_create_users_table.php │ │ ├── 2014_10_12_100000_create_password_reset_tokens_table.php │ │ ├── 2019_08_19_000000_create_failed_jobs_table.php │ │ ├── 2019_12_14_000001_create_personal_access_tokens_table.php │ │ ├── 2023_08_28_231316_create_events_table.php │ │ ├── 2023_08_28_231342_create_attendees_table.php │ │ └── 2023_09_03_235309_create_jobs_table.php │ └── seeders │ │ ├── AttendeeSeeder.php │ │ ├── DatabaseSeeder.php │ │ └── EventSeeder.php ├── package.json ├── phpunit.xml ├── public │ ├── .htaccess │ ├── favicon.ico │ ├── index.php │ └── robots.txt ├── resources │ ├── css │ │ └── app.css │ ├── js │ │ ├── app.js │ │ └── bootstrap.js │ └── views │ │ └── welcome.blade.php ├── routes │ ├── api.php │ ├── channels.php │ ├── console.php │ └── web.php ├── storage │ ├── app │ │ ├── .gitignore │ │ └── public │ │ │ └── .gitignore │ ├── framework │ │ ├── .gitignore │ │ ├── cache │ │ │ ├── .gitignore │ │ │ └── data │ │ │ │ └── .gitignore │ │ ├── sessions │ │ │ └── .gitignore │ │ ├── testing │ │ │ └── .gitignore │ │ └── views │ │ │ └── .gitignore │ └── logs │ │ └── .gitignore ├── tests │ ├── CreatesApplication.php │ ├── Feature │ │ └── ExampleTest.php │ ├── TestCase.php │ └── Unit │ │ └── ExampleTest.php └── vite.config.js ├── job-board ├── .editorconfig ├── .env.example ├── .gitattributes ├── .gitignore ├── README.md ├── app │ ├── Console │ │ └── Kernel.php │ ├── Exceptions │ │ └── Handler.php │ ├── Http │ │ ├── Controllers │ │ │ ├── AuthController.php │ │ │ ├── Controller.php │ │ │ ├── JobApplicationController.php │ │ │ ├── JobController.php │ │ │ └── MyJobApplicationController.php │ │ ├── Kernel.php │ │ └── Middleware │ │ │ ├── Authenticate.php │ │ │ ├── EncryptCookies.php │ │ │ ├── PreventRequestsDuringMaintenance.php │ │ │ ├── RedirectIfAuthenticated.php │ │ │ ├── TrimStrings.php │ │ │ ├── TrustHosts.php │ │ │ ├── TrustProxies.php │ │ │ ├── ValidateSignature.php │ │ │ └── VerifyCsrfToken.php │ ├── Models │ │ ├── Employer.php │ │ ├── Job.php │ │ ├── JobApplication.php │ │ └── User.php │ ├── Policies │ │ └── JobPolicy.php │ ├── Providers │ │ ├── AppServiceProvider.php │ │ ├── AuthServiceProvider.php │ │ ├── BroadcastServiceProvider.php │ │ ├── EventServiceProvider.php │ │ └── RouteServiceProvider.php │ └── View │ │ └── Components │ │ ├── Breadcrumbs.php │ │ ├── Button.php │ │ ├── Card.php │ │ ├── JobCard.php │ │ ├── Label.php │ │ ├── Layout.php │ │ ├── LinkButton.php │ │ ├── RadioGroup.php │ │ ├── Tag.php │ │ └── TextInput.php ├── artisan ├── bootstrap │ ├── app.php │ └── cache │ │ └── .gitignore ├── composer.json ├── composer.lock ├── config │ ├── app.php │ ├── auth.php │ ├── broadcasting.php │ ├── cache.php │ ├── cors.php │ ├── database.php │ ├── filesystems.php │ ├── hashing.php │ ├── logging.php │ ├── mail.php │ ├── queue.php │ ├── sanctum.php │ ├── services.php │ ├── session.php │ └── view.php ├── database │ ├── .gitignore │ ├── factories │ │ ├── EmployerFactory.php │ │ ├── JobApplicationFactory.php │ │ ├── JobFactory.php │ │ └── UserFactory.php │ ├── migrations │ │ ├── 2014_10_12_000000_create_users_table.php │ │ ├── 2014_10_12_100000_create_password_reset_tokens_table.php │ │ ├── 2019_08_19_000000_create_failed_jobs_table.php │ │ ├── 2019_12_14_000001_create_personal_access_tokens_table.php │ │ ├── 2023_09_07_210714_create_jobs_table.php │ │ ├── 2023_09_22_213945_create_employers_table.php │ │ ├── 2023_09_24_183103_create_job_applications_table.php │ │ └── 2023_09_26_173615_add_cv_path_to_job_applications_table.php │ └── seeders │ │ └── DatabaseSeeder.php ├── package-lock.json ├── package.json ├── phpunit.xml ├── postcss.config.js ├── public │ ├── .htaccess │ ├── favicon.ico │ ├── index.php │ └── robots.txt ├── resources │ ├── css │ │ └── app.css │ ├── js │ │ ├── app.js │ │ └── bootstrap.js │ └── views │ │ ├── auth │ │ └── create.blade.php │ │ ├── components │ │ ├── breadcrumbs.blade.php │ │ ├── button.blade.php │ │ ├── card.blade.php │ │ ├── job-card.blade.php │ │ ├── label.blade.php │ │ ├── layout.blade.php │ │ ├── link-button.blade.php │ │ ├── radio-group.blade.php │ │ ├── tag.blade.php │ │ └── text-input.blade.php │ │ ├── job │ │ ├── index.blade.php │ │ └── show.blade.php │ │ ├── job_application │ │ └── create.blade.php │ │ └── my_job_application │ │ └── index.blade.php ├── routes │ ├── api.php │ ├── channels.php │ ├── console.php │ └── web.php ├── storage │ ├── app │ │ ├── .gitignore │ │ └── public │ │ │ └── .gitignore │ ├── debugbar │ │ └── .gitignore │ ├── framework │ │ ├── .gitignore │ │ ├── cache │ │ │ ├── .gitignore │ │ │ └── data │ │ │ │ └── .gitignore │ │ ├── sessions │ │ │ └── .gitignore │ │ ├── testing │ │ │ └── .gitignore │ │ └── views │ │ │ └── .gitignore │ └── logs │ │ └── .gitignore ├── tailwind.config.js ├── tests │ ├── CreatesApplication.php │ ├── Feature │ │ └── ExampleTest.php │ ├── TestCase.php │ └── Unit │ │ └── ExampleTest.php └── vite.config.js └── livewire-poll ├── .editorconfig ├── .env.example ├── .gitattributes ├── .gitignore ├── README.md ├── app ├── Console │ └── Kernel.php ├── Exceptions │ └── Handler.php ├── Http │ ├── Controllers │ │ └── Controller.php │ ├── Kernel.php │ ├── Livewire │ │ ├── CreatePoll.php │ │ └── Polls.php │ └── Middleware │ │ ├── Authenticate.php │ │ ├── EncryptCookies.php │ │ ├── PreventRequestsDuringMaintenance.php │ │ ├── RedirectIfAuthenticated.php │ │ ├── TrimStrings.php │ │ ├── TrustHosts.php │ │ ├── TrustProxies.php │ │ ├── ValidateSignature.php │ │ └── VerifyCsrfToken.php ├── Models │ ├── Option.php │ ├── Poll.php │ ├── User.php │ └── Vote.php └── Providers │ ├── AppServiceProvider.php │ ├── AuthServiceProvider.php │ ├── BroadcastServiceProvider.php │ ├── EventServiceProvider.php │ └── RouteServiceProvider.php ├── artisan ├── bootstrap ├── app.php └── cache │ └── .gitignore ├── composer.json ├── composer.lock ├── config ├── app.php ├── auth.php ├── broadcasting.php ├── cache.php ├── cors.php ├── database.php ├── filesystems.php ├── hashing.php ├── logging.php ├── mail.php ├── queue.php ├── sanctum.php ├── services.php ├── session.php └── view.php ├── database ├── .gitignore ├── factories │ └── UserFactory.php ├── migrations │ ├── 2014_10_12_000000_create_users_table.php │ ├── 2014_10_12_100000_create_password_reset_tokens_table.php │ ├── 2019_08_19_000000_create_failed_jobs_table.php │ ├── 2019_12_14_000001_create_personal_access_tokens_table.php │ ├── 2023_09_04_010105_create_polls_table.php │ ├── 2023_09_04_010155_create_options_table.php │ └── 2023_09_04_010156_create_votes_table.php └── seeders │ └── DatabaseSeeder.php ├── package.json ├── phpunit.xml ├── public ├── .htaccess ├── favicon.ico ├── index.php └── robots.txt ├── resources ├── css │ └── app.css ├── js │ ├── app.js │ └── bootstrap.js └── views │ ├── app.blade.php │ └── livewire │ ├── create-poll.blade.php │ └── polls.blade.php ├── routes ├── api.php ├── channels.php ├── console.php └── web.php ├── storage ├── app │ ├── .gitignore │ └── public │ │ └── .gitignore ├── framework │ ├── .gitignore │ ├── cache │ │ ├── .gitignore │ │ └── data │ │ │ └── .gitignore │ ├── sessions │ │ └── .gitignore │ ├── testing │ │ └── .gitignore │ └── views │ │ └── .gitignore └── logs │ └── .gitignore ├── tests ├── CreatesApplication.php ├── Feature │ └── ExampleTest.php ├── TestCase.php └── Unit │ └── ExampleTest.php └── vite.config.js /Book-reviews-project/app/Console/Kernel.php: -------------------------------------------------------------------------------- 1 | command('inspire')->hourly(); 16 | } 17 | 18 | /** 19 | * Register the commands for the application. 20 | */ 21 | protected function commands(): void 22 | { 23 | $this->load(__DIR__.'/Commands'); 24 | 25 | require base_path('routes/console.php'); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Book-reviews-project/app/Exceptions/Handler.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | protected $dontFlash = [ 16 | 'current_password', 17 | 'password', 18 | 'password_confirmation', 19 | ]; 20 | 21 | /** 22 | * Register the exception handling callbacks for the application. 23 | */ 24 | public function register(): void 25 | { 26 | $this->reportable(function (Throwable $e) { 27 | // 28 | }); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Book-reviews-project/app/Http/Controllers/Controller.php: -------------------------------------------------------------------------------- 1 | expectsJson() ? null : route('login'); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Book-reviews-project/app/Http/Middleware/EncryptCookies.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /Book-reviews-project/app/Http/Middleware/PreventRequestsDuringMaintenance.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /Book-reviews-project/app/Http/Middleware/RedirectIfAuthenticated.php: -------------------------------------------------------------------------------- 1 | check()) { 24 | return redirect(RouteServiceProvider::HOME); 25 | } 26 | } 27 | 28 | return $next($request); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Book-reviews-project/app/Http/Middleware/TrimStrings.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | 'current_password', 16 | 'password', 17 | 'password_confirmation', 18 | ]; 19 | } 20 | -------------------------------------------------------------------------------- /Book-reviews-project/app/Http/Middleware/TrustHosts.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | public function hosts(): array 15 | { 16 | return [ 17 | $this->allSubdomainsOfApplicationUrl(), 18 | ]; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Book-reviews-project/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 | -------------------------------------------------------------------------------- /Book-reviews-project/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 | -------------------------------------------------------------------------------- /Book-reviews-project/app/Http/Middleware/VerifyCsrfToken.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /Book-reviews-project/app/Models/Review.php: -------------------------------------------------------------------------------- 1 | belongsTo(Book::class); 17 | } 18 | 19 | 20 | static function booted() 21 | { 22 | static::updated(fn(Review $review)=> cache()->forget('book:'. $review->book_id) ); 23 | static::deleted(fn(Review $review)=> cache()->forget('book:'. $review->book_id) ); 24 | static::created(fn(Review $review)=> cache()->forget('book:'. $review->book_id) ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Book-reviews-project/app/Models/User.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | protected $fillable = [ 21 | 'name', 22 | 'email', 23 | 'password', 24 | ]; 25 | 26 | /** 27 | * The attributes that should be hidden for serialization. 28 | * 29 | * @var array 30 | */ 31 | protected $hidden = [ 32 | 'password', 33 | 'remember_token', 34 | ]; 35 | 36 | /** 37 | * The attributes that should be cast. 38 | * 39 | * @var array 40 | */ 41 | protected $casts = [ 42 | 'email_verified_at' => 'datetime', 43 | 'password' => 'hashed', 44 | ]; 45 | } 46 | -------------------------------------------------------------------------------- /Book-reviews-project/app/Providers/AppServiceProvider.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | protected $policies = [ 16 | // 17 | ]; 18 | 19 | /** 20 | * Register any authentication / authorization services. 21 | */ 22 | public function boot(): void 23 | { 24 | // 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Book-reviews-project/app/Providers/BroadcastServiceProvider.php: -------------------------------------------------------------------------------- 1 | > 16 | */ 17 | protected $listen = [ 18 | Registered::class => [ 19 | SendEmailVerificationNotification::class, 20 | ], 21 | ]; 22 | 23 | /** 24 | * Register any events for your application. 25 | */ 26 | 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 | -------------------------------------------------------------------------------- /Book-reviews-project/app/Providers/RouteServiceProvider.php: -------------------------------------------------------------------------------- 1 | by($request->user()?->id ?: $request->ip()); 29 | }); 30 | 31 | RateLimiter::for('reviews', function (Request $request) { 32 | return Limit::perHour(1)->by($request->user()?->id ?: $request->ip()); 33 | }); 34 | 35 | $this->routes(function () { 36 | Route::middleware('api') 37 | ->prefix('api') 38 | ->group(base_path('routes/api.php')); 39 | 40 | Route::middleware('web') 41 | ->group(base_path('routes/web.php')); 42 | }); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Book-reviews-project/app/View/Components/StarRating.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 | -------------------------------------------------------------------------------- /Book-reviews-project/config/services.php: -------------------------------------------------------------------------------- 1 | [ 18 | 'domain' => env('MAILGUN_DOMAIN'), 19 | 'secret' => env('MAILGUN_SECRET'), 20 | 'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'), 21 | 'scheme' => 'https', 22 | ], 23 | 24 | 'postmark' => [ 25 | 'token' => env('POSTMARK_TOKEN'), 26 | ], 27 | 28 | 'ses' => [ 29 | 'key' => env('AWS_ACCESS_KEY_ID'), 30 | 'secret' => env('AWS_SECRET_ACCESS_KEY'), 31 | 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), 32 | ], 33 | 34 | ]; 35 | -------------------------------------------------------------------------------- /Book-reviews-project/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 | -------------------------------------------------------------------------------- /Book-reviews-project/database/.gitignore: -------------------------------------------------------------------------------- 1 | *.sqlite* 2 | -------------------------------------------------------------------------------- /Book-reviews-project/database/factories/BookFactory.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class BookFactory extends Factory 11 | { 12 | /** 13 | * Define the model's default state. 14 | * 15 | * @return array 16 | */ 17 | public function definition(): array 18 | { 19 | return [ 20 | 'title' => fake()->sentence(3), 21 | 'author' => fake()->name, 22 | 'created_at'=>fake()->dateTimeBetween('-2 years'), 23 | 'updated_at'=>fake()->dateTimeBetween('created_at','now'), 24 | ]; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Book-reviews-project/database/factories/ReviewFactory.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class ReviewFactory extends Factory 11 | { 12 | /** 13 | * Define the model's default state. 14 | * 15 | * @return array 16 | */ 17 | public function definition(): array 18 | { 19 | return [ 20 | 'book_id' => null, 21 | 'review'=>fake()->paragraph, 22 | 'rating'=>fake()->numberBetween(1,5), 23 | 'created_at'=>fake()->dateTimeBetween('-2 years'), 24 | 'updated_at'=>fake()->dateTimeBetween('created_at','now'), 25 | ]; 26 | } 27 | 28 | public function average(){ 29 | 30 | return $this->state(function(array $attribute){ 31 | return[ 32 | 'rating'=>fake()->numberBetween(2,4), 33 | ]; 34 | }); 35 | } 36 | 37 | public function good(){ 38 | 39 | return $this->state(function(array $attribute){ 40 | return[ 41 | 'rating'=>fake()->numberBetween(4,5), 42 | ]; 43 | }); 44 | } 45 | 46 | public function bad(){ 47 | 48 | return $this->state(function(array $attribute){ 49 | return[ 50 | 'rating'=>fake()->numberBetween(1,3), 51 | ]; 52 | }); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Book-reviews-project/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 | -------------------------------------------------------------------------------- /Book-reviews-project/database/migrations/2014_10_12_000000_create_users_table.php: -------------------------------------------------------------------------------- 1 | id(); 16 | $table->string('name'); 17 | $table->string('email')->unique(); 18 | $table->timestamp('email_verified_at')->nullable(); 19 | $table->string('password'); 20 | $table->rememberToken(); 21 | $table->timestamps(); 22 | }); 23 | } 24 | 25 | /** 26 | * Reverse the migrations. 27 | */ 28 | public function down(): void 29 | { 30 | Schema::dropIfExists('users'); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /Book-reviews-project/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 | -------------------------------------------------------------------------------- /Book-reviews-project/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 | -------------------------------------------------------------------------------- /Book-reviews-project/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 | -------------------------------------------------------------------------------- /Book-reviews-project/database/migrations/2023_08_24_114736_create_books_table.php: -------------------------------------------------------------------------------- 1 | id(); 17 | $table->string('title'); 18 | $table->string('author'); 19 | $table->timestamps(); 20 | 21 | 22 | }); 23 | } 24 | 25 | /** 26 | * Reverse the migrations. 27 | */ 28 | public function down(): void 29 | { 30 | Schema::dropIfExists('books'); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /Book-reviews-project/database/migrations/2023_08_24_114750_create_reviews_table.php: -------------------------------------------------------------------------------- 1 | id(); 17 | // $table->unsignedBigInteger('book_id'); 18 | $table->text('review'); 19 | $table->unsignedBigInteger('rating'); 20 | $table->timestamps(); 21 | // $table->foreign('book_id')->references('id')->on('books')->onDelete('cascade'); 22 | $table->foreignId('book_id')->constrained()->cascadeOnDelete(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | */ 29 | public function down(): void 30 | { 31 | Schema::dropIfExists('reviews'); 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /Book-reviews-project/database/seeders/DatabaseSeeder.php: -------------------------------------------------------------------------------- 1 | create()->each(function($book){ 19 | $numberReviews = random_int(5,30); 20 | 21 | Review::factory()->count($numberReviews) 22 | ->good() 23 | ->for($book) 24 | ->create(); 25 | }); 26 | Book::factory(33)->create()->each(function($book){ 27 | $numberReviews = random_int(5,30); 28 | 29 | Review::factory()->count($numberReviews) 30 | ->average() 31 | ->for($book) 32 | ->create(); 33 | }); 34 | Book::factory(34)->create()->each(function($book){ 35 | $numberReviews = random_int(5,30); 36 | 37 | Review::factory()->count($numberReviews) 38 | ->bad() 39 | ->for($book) 40 | ->create(); 41 | }); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Book-reviews-project/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "type": "module", 4 | "scripts": { 5 | "dev": "vite", 6 | "build": "vite build" 7 | }, 8 | "devDependencies": { 9 | "axios": "^1.1.2", 10 | "laravel-vite-plugin": "^0.8.0", 11 | "vite": "^4.0.0" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Book-reviews-project/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 | -------------------------------------------------------------------------------- /Book-reviews-project/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 | -------------------------------------------------------------------------------- /Book-reviews-project/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moemen12/laravel-projects/6e6181d69cbb59fb1e01b9c87044bb687f375fd4/Book-reviews-project/public/favicon.ico -------------------------------------------------------------------------------- /Book-reviews-project/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /Book-reviews-project/resources/css/app.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moemen12/laravel-projects/6e6181d69cbb59fb1e01b9c87044bb687f375fd4/Book-reviews-project/resources/css/app.css -------------------------------------------------------------------------------- /Book-reviews-project/resources/js/app.js: -------------------------------------------------------------------------------- 1 | import './bootstrap'; 2 | -------------------------------------------------------------------------------- /Book-reviews-project/resources/js/bootstrap.js: -------------------------------------------------------------------------------- 1 | /** 2 | * We'll load the axios HTTP library which allows us to easily issue requests 3 | * to our Laravel back-end. This library automatically handles sending the 4 | * CSRF token as a header based on the value of the "XSRF" token cookie. 5 | */ 6 | 7 | import axios from 'axios'; 8 | window.axios = axios; 9 | 10 | window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; 11 | 12 | /** 13 | * Echo exposes an expressive API for subscribing to channels and listening 14 | * for events that are broadcast by Laravel. Echo and event broadcasting 15 | * allows your team to easily build robust real-time web applications. 16 | */ 17 | 18 | // import Echo from 'laravel-echo'; 19 | 20 | // import Pusher from 'pusher-js'; 21 | // window.Pusher = Pusher; 22 | 23 | // window.Echo = new Echo({ 24 | // broadcaster: 'pusher', 25 | // key: import.meta.env.VITE_PUSHER_APP_KEY, 26 | // cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER ?? 'mt1', 27 | // wsHost: import.meta.env.VITE_PUSHER_HOST ? import.meta.env.VITE_PUSHER_HOST : `ws-${import.meta.env.VITE_PUSHER_APP_CLUSTER}.pusher.com`, 28 | // wsPort: import.meta.env.VITE_PUSHER_PORT ?? 80, 29 | // wssPort: import.meta.env.VITE_PUSHER_PORT ?? 443, 30 | // forceTLS: (import.meta.env.VITE_PUSHER_SCHEME ?? 'https') === 'https', 31 | // enabledTransports: ['ws', 'wss'], 32 | // }); 33 | -------------------------------------------------------------------------------- /Book-reviews-project/resources/views/books/reviews/create.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |

Add Review for {{ $book->title }}

5 | 6 |
7 | @csrf 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 21 | 22 |
23 | @endsection -------------------------------------------------------------------------------- /Book-reviews-project/resources/views/components/star-rating.blade.php: -------------------------------------------------------------------------------- 1 | @if ($rating) 2 | @for ($i = 1; $i <= 5; $i++) 3 | {{ $i <= round($rating) ? '★' : '☆' }} 4 | @endfor 5 | @else 6 | No rating yet 7 | @endif -------------------------------------------------------------------------------- /Book-reviews-project/routes/api.php: -------------------------------------------------------------------------------- 1 | get('/user', function (Request $request) { 18 | return $request->user(); 19 | }); 20 | -------------------------------------------------------------------------------- /Book-reviews-project/routes/channels.php: -------------------------------------------------------------------------------- 1 | id === (int) $id; 18 | }); 19 | -------------------------------------------------------------------------------- /Book-reviews-project/routes/console.php: -------------------------------------------------------------------------------- 1 | comment(Inspiring::quote()); 19 | })->purpose('Display an inspiring quote'); 20 | -------------------------------------------------------------------------------- /Book-reviews-project/routes/web.php: -------------------------------------------------------------------------------- 1 | route('books.index'); 20 | }); 21 | 22 | Route::resource('books', BookController::class)->only(['index','show']); 23 | 24 | Route::resource('books.reviews', ReviewController::class)->scoped([ 25 | 'review' => 'book' 26 | ])->only(['create','store']); -------------------------------------------------------------------------------- /Book-reviews-project/storage/app/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !public/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /Book-reviews-project/storage/app/public/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /Book-reviews-project/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 | -------------------------------------------------------------------------------- /Book-reviews-project/storage/framework/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !data/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /Book-reviews-project/storage/framework/cache/data/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /Book-reviews-project/storage/framework/sessions/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /Book-reviews-project/storage/framework/testing/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /Book-reviews-project/storage/framework/views/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /Book-reviews-project/storage/logs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /Book-reviews-project/tests/CreatesApplication.php: -------------------------------------------------------------------------------- 1 | make(Kernel::class)->bootstrap(); 18 | 19 | return $app; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Book-reviews-project/tests/Feature/ExampleTest.php: -------------------------------------------------------------------------------- 1 | get('/'); 16 | 17 | $response->assertStatus(200); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Book-reviews-project/tests/TestCase.php: -------------------------------------------------------------------------------- 1 | assertTrue(true); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Book-reviews-project/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import laravel from 'laravel-vite-plugin'; 3 | 4 | export default defineConfig({ 5 | plugins: [ 6 | laravel({ 7 | input: ['resources/css/app.css', 'resources/js/app.js'], 8 | refresh: true, 9 | }), 10 | ], 11 | }); 12 | -------------------------------------------------------------------------------- /event-management/.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 = true 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 | -------------------------------------------------------------------------------- /event-management/.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_APP_NAME="${APP_NAME}" 55 | VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}" 56 | VITE_PUSHER_HOST="${PUSHER_HOST}" 57 | VITE_PUSHER_PORT="${PUSHER_PORT}" 58 | VITE_PUSHER_SCHEME="${PUSHER_SCHEME}" 59 | VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" 60 | -------------------------------------------------------------------------------- /event-management/.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 | -------------------------------------------------------------------------------- /event-management/.gitignore: -------------------------------------------------------------------------------- 1 | /.phpunit.cache 2 | /node_modules 3 | /public/build 4 | /public/hot 5 | /public/storage 6 | /storage/*.key 7 | /vendor 8 | .env 9 | .env.backup 10 | .env.production 11 | .phpunit.result.cache 12 | Homestead.json 13 | Homestead.yaml 14 | auth.json 15 | npm-debug.log 16 | yarn-error.log 17 | /.fleet 18 | /.idea 19 | /.vscode 20 | -------------------------------------------------------------------------------- /event-management/app/Console/Commands/SendEventReminders.php: -------------------------------------------------------------------------------- 1 | whereBetween('start_time', [now(), now()->addDay()])->get(); 33 | 34 | $eventCount = $events->count(); 35 | $eventLabel = Str::plural('event ', $eventCount); 36 | $this->info("Found {$eventCount} {$eventLabel}"); 37 | 38 | $events->each( 39 | fn ($event) => $event->attendees->each( 40 | fn ($attendee) => $attendee->user->notify( 41 | new EventReminderNotification( 42 | $event 43 | ) 44 | ) 45 | ) 46 | ); 47 | 48 | 49 | $this->info('Reminder notifications sent successfully'); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /event-management/app/Console/Kernel.php: -------------------------------------------------------------------------------- 1 | command('app:send-event-reminders')->everyMinute(); 16 | } 17 | 18 | /** 19 | * Register the commands for the application. 20 | */ 21 | protected function commands(): void 22 | { 23 | $this->load(__DIR__.'/Commands'); 24 | 25 | require base_path('routes/console.php'); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /event-management/app/Exceptions/Handler.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | protected $dontFlash = [ 16 | 'current_password', 17 | 'password', 18 | 'password_confirmation', 19 | ]; 20 | 21 | /** 22 | * Register the exception handling callbacks for the application. 23 | */ 24 | public function register(): void 25 | { 26 | $this->reportable(function (Throwable $e) { 27 | // 28 | }); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /event-management/app/Http/Controllers/Api/AuthController.php: -------------------------------------------------------------------------------- 1 | validate([ 16 | 'email'=>'required|email', 17 | 'password'=>'required' 18 | ]); 19 | 20 | $user = User::where('email',$request->email)->first(); 21 | 22 | if(!$user){ 23 | throw ValidationException::withMessages([ 24 | 'email'=> 'The Provided credentials are incorrect.' 25 | ]); 26 | } 27 | if(!Hash::check($request->password,$user->password)){ 28 | throw ValidationException::withMessages([ 29 | 'email'=> 'The Provided credentials are incorrect.' 30 | ]); 31 | } 32 | 33 | $token = $user->createToken('api-token')->plainTextToken; 34 | 35 | return response()->json([ 36 | 'token' => $token 37 | ]); 38 | } 39 | 40 | 41 | public function logout(Request $request){ 42 | $request->user()->tokens()->delete(); 43 | return response()->json([ 44 | 'message' => 'Logged out successfully' 45 | ]); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /event-management/app/Http/Controllers/Controller.php: -------------------------------------------------------------------------------- 1 | expectsJson() ? null : route('login'); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /event-management/app/Http/Middleware/EncryptCookies.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /event-management/app/Http/Middleware/PreventRequestsDuringMaintenance.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /event-management/app/Http/Middleware/RedirectIfAuthenticated.php: -------------------------------------------------------------------------------- 1 | check()) { 24 | return redirect(RouteServiceProvider::HOME); 25 | } 26 | } 27 | 28 | return $next($request); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /event-management/app/Http/Middleware/TrimStrings.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | 'current_password', 16 | 'password', 17 | 'password_confirmation', 18 | ]; 19 | } 20 | -------------------------------------------------------------------------------- /event-management/app/Http/Middleware/TrustHosts.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | public function hosts(): array 15 | { 16 | return [ 17 | $this->allSubdomainsOfApplicationUrl(), 18 | ]; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /event-management/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 | -------------------------------------------------------------------------------- /event-management/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 | -------------------------------------------------------------------------------- /event-management/app/Http/Middleware/VerifyCsrfToken.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /event-management/app/Http/Resources/AttendeeResource.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | public function toArray(Request $request): array 16 | { 17 | return parent::toArray($request); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /event-management/app/Http/Resources/EventResource.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | public function toArray(Request $request): array 16 | { 17 | return [ 18 | 'id' => $this->id, 19 | 'name'=> $this->name, 20 | 'description'=>$this->description, 21 | 'start_time' => $this->start_time, 22 | 'end_time' => $this->end_time, 23 | 'user'=> new UserResource($this->whenLoaded('user')), 24 | 'attendees'=>AttendeeResource::collection($this->whenLoaded('attendees')) 25 | ]; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /event-management/app/Http/Resources/UserResource.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | public function toArray(Request $request): array 16 | { 17 | return parent::toArray($request); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /event-management/app/Http/Traits/CanLoadRelationships.php: -------------------------------------------------------------------------------- 1 | relations ?? []; // ['user'] 20 | foreach($relations as $relation){ 21 | $for->when( 22 | $this->shouldIncludeRelations($relation), 23 | fn($q)=> $for instanceof Model ? $for->load($relation) : $q->with($relation) 24 | ); 25 | } 26 | 27 | return $for; 28 | 29 | } 30 | 31 | protected function shouldIncludeRelations(string $relation):bool 32 | { 33 | $include = request()->query('include'); //user 34 | 35 | if(!$include){ 36 | return false; 37 | } 38 | 39 | $relations= array_map('trim',explode(',',$include)); // ['user'] 40 | // return in_array($relation,['user']); 41 | return in_array($relation,$relations); 42 | } 43 | 44 | 45 | 46 | } -------------------------------------------------------------------------------- /event-management/app/Models/Attendee.php: -------------------------------------------------------------------------------- 1 | belongsTo(User::class); 18 | } 19 | 20 | public function event():BelongsTo 21 | { 22 | return $this->belongsTo(Event::class); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /event-management/app/Models/Event.php: -------------------------------------------------------------------------------- 1 | belongsTo(User::class); 20 | } 21 | 22 | public function attendees(): HasMany 23 | { 24 | return $this->hasMany(Attendee::class); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /event-management/app/Models/User.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | protected $fillable = [ 21 | 'name', 22 | 'email', 23 | 'password', 24 | ]; 25 | 26 | /** 27 | * The attributes that should be hidden for serialization. 28 | * 29 | * @var array 30 | */ 31 | protected $hidden = [ 32 | 'password', 33 | 'remember_token', 34 | ]; 35 | 36 | /** 37 | * The attributes that should be cast. 38 | * 39 | * @var array 40 | */ 41 | protected $casts = [ 42 | 'email_verified_at' => 'datetime', 43 | 'password' => 'hashed', 44 | ]; 45 | } 46 | -------------------------------------------------------------------------------- /event-management/app/Policies/EventPolicy.php: -------------------------------------------------------------------------------- 1 | id === $event->user_id; 41 | } 42 | 43 | /** 44 | * Determine whether the user can delete the model. 45 | */ 46 | public function delete(User $user, Event $event): bool 47 | { 48 | return $user->id === $event->user_id; 49 | } 50 | 51 | /** 52 | * Determine whether the user can restore the model. 53 | */ 54 | public function restore(User $user, Event $event): bool 55 | { 56 | // 57 | } 58 | 59 | /** 60 | * Determine whether the user can permanently delete the model. 61 | */ 62 | public function forceDelete(User $user, Event $event): bool 63 | { 64 | // 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /event-management/app/Providers/AppServiceProvider.php: -------------------------------------------------------------------------------- 1 | 18 | */ 19 | protected $policies = [ 20 | 21 | ]; 22 | 23 | /** 24 | * Register any authentication / authorization services. 25 | */ 26 | public function boot(): void 27 | { 28 | // Gate::define('update-event',function($user,Event $event){ 29 | // return $user->id === $event->user_id; 30 | // }); 31 | // Gate::define('delete-attendee',function($user,Event $event,Attendee $attendee){ 32 | // return $user->id === $event->user_id || $user->id === $attendee->user_id; 33 | // }); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /event-management/app/Providers/BroadcastServiceProvider.php: -------------------------------------------------------------------------------- 1 | > 16 | */ 17 | protected $listen = [ 18 | Registered::class => [ 19 | SendEmailVerificationNotification::class, 20 | ], 21 | ]; 22 | 23 | /** 24 | * Register any events for your application. 25 | */ 26 | 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 | -------------------------------------------------------------------------------- /event-management/app/Providers/RouteServiceProvider.php: -------------------------------------------------------------------------------- 1 | by($request->user()?->id ?: $request->ip()); 29 | }); 30 | 31 | $this->routes(function () { 32 | Route::middleware('api') 33 | ->prefix('api') 34 | ->group(base_path('routes/api.php')); 35 | 36 | Route::middleware('web') 37 | ->group(base_path('routes/web.php')); 38 | }); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /event-management/bootstrap/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /event-management/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 | -------------------------------------------------------------------------------- /event-management/config/services.php: -------------------------------------------------------------------------------- 1 | [ 18 | 'domain' => env('MAILGUN_DOMAIN'), 19 | 'secret' => env('MAILGUN_SECRET'), 20 | 'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'), 21 | 'scheme' => 'https', 22 | ], 23 | 24 | 'postmark' => [ 25 | 'token' => env('POSTMARK_TOKEN'), 26 | ], 27 | 28 | 'ses' => [ 29 | 'key' => env('AWS_ACCESS_KEY_ID'), 30 | 'secret' => env('AWS_SECRET_ACCESS_KEY'), 31 | 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), 32 | ], 33 | 34 | ]; 35 | -------------------------------------------------------------------------------- /event-management/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 | -------------------------------------------------------------------------------- /event-management/database/.gitignore: -------------------------------------------------------------------------------- 1 | *.sqlite* 2 | -------------------------------------------------------------------------------- /event-management/database/factories/EventFactory.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class EventFactory extends Factory 11 | { 12 | /** 13 | * Define the model's default state. 14 | * 15 | * @return array 16 | */ 17 | public function definition(): array 18 | { 19 | return [ 20 | 'name' => fake()->unique()->sentence(3), 21 | 'description'=>fake()->text, 22 | 'start_time' =>fake()->dateTimeBetween('now','+1 month'), 23 | 'end_time' =>fake()->dateTimeBetween('+1 month','+2 months'), 24 | ]; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /event-management/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 | -------------------------------------------------------------------------------- /event-management/database/migrations/2014_10_12_000000_create_users_table.php: -------------------------------------------------------------------------------- 1 | id(); 16 | $table->string('name'); 17 | $table->string('email')->unique(); 18 | $table->timestamp('email_verified_at')->nullable(); 19 | $table->string('password'); 20 | $table->rememberToken(); 21 | $table->timestamps(); 22 | }); 23 | } 24 | 25 | /** 26 | * Reverse the migrations. 27 | */ 28 | public function down(): void 29 | { 30 | Schema::dropIfExists('users'); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /event-management/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 | -------------------------------------------------------------------------------- /event-management/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 | -------------------------------------------------------------------------------- /event-management/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 | -------------------------------------------------------------------------------- /event-management/database/migrations/2023_08_28_231316_create_events_table.php: -------------------------------------------------------------------------------- 1 | id(); 17 | 18 | $table->foreignIdFor(User::class); 19 | $table->string('name'); 20 | $table->text('description')->nullable(); 21 | $table->dateTime('start_time'); 22 | $table->dateTime('end_time'); 23 | $table->timestamps(); 24 | }); 25 | } 26 | 27 | /** 28 | * Reverse the migrations. 29 | */ 30 | public function down(): void 31 | { 32 | Schema::dropIfExists('events'); 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /event-management/database/migrations/2023_08_28_231342_create_attendees_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->foreignIdFor(User::class); 19 | $table->foreignIdFor(Event::class); 20 | $table->timestamps(); 21 | }); 22 | } 23 | 24 | /** 25 | * Reverse the migrations. 26 | */ 27 | public function down(): void 28 | { 29 | Schema::dropIfExists('attendees'); 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /event-management/database/migrations/2023_09_03_235309_create_jobs_table.php: -------------------------------------------------------------------------------- 1 | bigIncrements('id'); 16 | $table->string('queue')->index(); 17 | $table->longText('payload'); 18 | $table->unsignedTinyInteger('attempts'); 19 | $table->unsignedInteger('reserved_at')->nullable(); 20 | $table->unsignedInteger('available_at'); 21 | $table->unsignedInteger('created_at'); 22 | }); 23 | } 24 | 25 | /** 26 | * Reverse the migrations. 27 | */ 28 | public function down(): void 29 | { 30 | Schema::dropIfExists('jobs'); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /event-management/database/seeders/AttendeeSeeder.php: -------------------------------------------------------------------------------- 1 | random(rand(1,3)); 23 | 24 | 25 | 26 | foreach($eventsToAttend as $event){ 27 | Attendee::create([ 28 | 'user_id' => $user->id, 29 | 'event_id'=>$event->id 30 | ]); 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /event-management/database/seeders/DatabaseSeeder.php: -------------------------------------------------------------------------------- 1 | create(); 16 | 17 | $this->call(EventSeeder::class); 18 | $this->call(AttendeeSeeder::class); 19 | // \App\Models\User::factory()->create([ 20 | // 'name' => 'Test User', 21 | // 'email' => 'test@example.com', 22 | // ]); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /event-management/database/seeders/EventSeeder.php: -------------------------------------------------------------------------------- 1 | random(); 21 | Event::factory()->create([ 22 | 'user_id' => $user->id 23 | ]); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /event-management/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "type": "module", 4 | "scripts": { 5 | "dev": "vite", 6 | "build": "vite build" 7 | }, 8 | "devDependencies": { 9 | "axios": "^1.1.2", 10 | "laravel-vite-plugin": "^0.8.0", 11 | "vite": "^4.0.0" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /event-management/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 | -------------------------------------------------------------------------------- /event-management/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 | -------------------------------------------------------------------------------- /event-management/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moemen12/laravel-projects/6e6181d69cbb59fb1e01b9c87044bb687f375fd4/event-management/public/favicon.ico -------------------------------------------------------------------------------- /event-management/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /event-management/resources/css/app.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moemen12/laravel-projects/6e6181d69cbb59fb1e01b9c87044bb687f375fd4/event-management/resources/css/app.css -------------------------------------------------------------------------------- /event-management/resources/js/app.js: -------------------------------------------------------------------------------- 1 | import './bootstrap'; 2 | -------------------------------------------------------------------------------- /event-management/resources/js/bootstrap.js: -------------------------------------------------------------------------------- 1 | /** 2 | * We'll load the axios HTTP library which allows us to easily issue requests 3 | * to our Laravel back-end. This library automatically handles sending the 4 | * CSRF token as a header based on the value of the "XSRF" token cookie. 5 | */ 6 | 7 | import axios from 'axios'; 8 | window.axios = axios; 9 | 10 | window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; 11 | 12 | /** 13 | * Echo exposes an expressive API for subscribing to channels and listening 14 | * for events that are broadcast by Laravel. Echo and event broadcasting 15 | * allows your team to easily build robust real-time web applications. 16 | */ 17 | 18 | // import Echo from 'laravel-echo'; 19 | 20 | // import Pusher from 'pusher-js'; 21 | // window.Pusher = Pusher; 22 | 23 | // window.Echo = new Echo({ 24 | // broadcaster: 'pusher', 25 | // key: import.meta.env.VITE_PUSHER_APP_KEY, 26 | // cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER ?? 'mt1', 27 | // wsHost: import.meta.env.VITE_PUSHER_HOST ? import.meta.env.VITE_PUSHER_HOST : `ws-${import.meta.env.VITE_PUSHER_APP_CLUSTER}.pusher.com`, 28 | // wsPort: import.meta.env.VITE_PUSHER_PORT ?? 80, 29 | // wssPort: import.meta.env.VITE_PUSHER_PORT ?? 443, 30 | // forceTLS: (import.meta.env.VITE_PUSHER_SCHEME ?? 'https') === 'https', 31 | // enabledTransports: ['ws', 'wss'], 32 | // }); 33 | -------------------------------------------------------------------------------- /event-management/routes/api.php: -------------------------------------------------------------------------------- 1 | get('/user', function (Request $request) { 21 | return $request->user(); 22 | }); 23 | 24 | 25 | Route::post('/login',[AuthController::class,'login']); 26 | Route::post('/logout',[AuthController::class,'logout'])->middleware('auth:sanctum'); 27 | Route::apiResource('events',EventController::class); 28 | Route::apiResource('events.attendees',AttendeeController::class)->scoped()->except('update'); -------------------------------------------------------------------------------- /event-management/routes/channels.php: -------------------------------------------------------------------------------- 1 | id === (int) $id; 18 | }); 19 | -------------------------------------------------------------------------------- /event-management/routes/console.php: -------------------------------------------------------------------------------- 1 | comment(Inspiring::quote()); 19 | })->purpose('Display an inspiring quote'); 20 | -------------------------------------------------------------------------------- /event-management/routes/web.php: -------------------------------------------------------------------------------- 1 | make(Kernel::class)->bootstrap(); 18 | 19 | return $app; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /event-management/tests/Feature/ExampleTest.php: -------------------------------------------------------------------------------- 1 | get('/'); 16 | 17 | $response->assertStatus(200); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /event-management/tests/TestCase.php: -------------------------------------------------------------------------------- 1 | assertTrue(true); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /event-management/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import laravel from 'laravel-vite-plugin'; 3 | 4 | export default defineConfig({ 5 | plugins: [ 6 | laravel({ 7 | input: ['resources/css/app.css', 'resources/js/app.js'], 8 | refresh: true, 9 | }), 10 | ], 11 | }); 12 | -------------------------------------------------------------------------------- /job-board/.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 = true 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 | -------------------------------------------------------------------------------- /job-board/.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_APP_NAME="${APP_NAME}" 55 | VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}" 56 | VITE_PUSHER_HOST="${PUSHER_HOST}" 57 | VITE_PUSHER_PORT="${PUSHER_PORT}" 58 | VITE_PUSHER_SCHEME="${PUSHER_SCHEME}" 59 | VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" 60 | -------------------------------------------------------------------------------- /job-board/.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 | -------------------------------------------------------------------------------- /job-board/.gitignore: -------------------------------------------------------------------------------- 1 | /.phpunit.cache 2 | /node_modules 3 | /public/build 4 | /public/hot 5 | /public/storage 6 | /storage/*.key 7 | /vendor 8 | .env 9 | .env.backup 10 | .env.production 11 | .phpunit.result.cache 12 | Homestead.json 13 | Homestead.yaml 14 | auth.json 15 | npm-debug.log 16 | yarn-error.log 17 | /.fleet 18 | /.idea 19 | /.vscode 20 | -------------------------------------------------------------------------------- /job-board/app/Console/Kernel.php: -------------------------------------------------------------------------------- 1 | command('inspire')->hourly(); 16 | } 17 | 18 | /** 19 | * Register the commands for the application. 20 | */ 21 | protected function commands(): void 22 | { 23 | $this->load(__DIR__.'/Commands'); 24 | 25 | require base_path('routes/console.php'); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /job-board/app/Exceptions/Handler.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | protected $dontFlash = [ 16 | 'current_password', 17 | 'password', 18 | 'password_confirmation', 19 | ]; 20 | 21 | /** 22 | * Register the exception handling callbacks for the application. 23 | */ 24 | public function register(): void 25 | { 26 | $this->reportable(function (Throwable $e) { 27 | // 28 | }); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /job-board/app/Http/Controllers/AuthController.php: -------------------------------------------------------------------------------- 1 | validate([ 28 | 'email' => 'required|email', 29 | 'password'=>'required' 30 | ]); 31 | 32 | $credentials = $request->only('email','password'); 33 | $remember = $request->filled('remember'); 34 | 35 | if(Auth::attempt($credentials,$remember)){ 36 | return redirect()->intended('/'); 37 | }else{ 38 | return redirect()->back()->with('error','Invalid credentials'); 39 | } 40 | } 41 | 42 | /** 43 | * Remove the specified resource from storage. 44 | */ 45 | public function destroy() 46 | { 47 | Auth::logout(); 48 | 49 | request()->session()->invalidate(); 50 | request()->session()->regenerateToken(); 51 | return redirect('/'); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /job-board/app/Http/Controllers/Controller.php: -------------------------------------------------------------------------------- 1 | authorize('apply',$job); 21 | return view('job_application.create',['job'=> $job]); 22 | } 23 | 24 | /** 25 | * Store a newly created resource in storage. 26 | */ 27 | public function store(Job $job,Request $request) 28 | { 29 | 30 | $validatedData= $request->validate([ 31 | 'expected_salary' =>'required|min:1|max:1000000', 32 | 'cv'=>'required|file|mimes:pdf|max:2048' 33 | ]); 34 | 35 | $file = $request->file('cv'); 36 | $path = $file->store('cvs','private'); 37 | 38 | $this->authorize('apply',$job); 39 | $job->jobApplications()->create([ 40 | 'user_id'=>$request->user()->id, 41 | 'expected_salary'=>$validatedData['expected_salary'], 42 | 'cv_path'=>$path 43 | ]); 44 | 45 | return redirect()->route('jobs.show',$job)->with('success','Job Application Submitted'); 46 | } 47 | 48 | 49 | } 50 | -------------------------------------------------------------------------------- /job-board/app/Http/Controllers/JobController.php: -------------------------------------------------------------------------------- 1 | only('search','min_salary','max_salary','category','experience'); 16 | return view('job.index', ['jobs' => Job::with('employer')->filter($filters)->get()]); 17 | 18 | } 19 | 20 | /** 21 | * Show the form for creating a new resource. 22 | */ 23 | public function create() 24 | { 25 | // 26 | } 27 | 28 | /** 29 | * Store a newly created resource in storage. 30 | */ 31 | public function store(Request $request) 32 | { 33 | // 34 | } 35 | 36 | /** 37 | * Display the specified resource. 38 | */ 39 | public function show(Job $job) 40 | { 41 | return view('job.show',['job'=> $job->load('employer')]); 42 | } 43 | 44 | /** 45 | * Show the form for editing the specified resource. 46 | */ 47 | public function edit(string $id) 48 | { 49 | // 50 | } 51 | 52 | /** 53 | * Update the specified resource in storage. 54 | */ 55 | public function update(Request $request, string $id) 56 | { 57 | // 58 | } 59 | 60 | /** 61 | * Remove the specified resource from storage. 62 | */ 63 | public function destroy(string $id) 64 | { 65 | // 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /job-board/app/Http/Controllers/MyJobApplicationController.php: -------------------------------------------------------------------------------- 1 | auth()->user()->jobApplication()->with([ 18 | 'job' => fn ($query) => $query->withCount('jobApplications') 19 | ->withAvg('jobApplications','expected_salary') 20 | , 'job.employer' 21 | ])->latest()->get() 22 | ]); 23 | 24 | 25 | } 26 | 27 | public function destroy(JobApplication $myJobApplication) 28 | { 29 | $myJobApplication->delete(); 30 | 31 | return redirect()->back()->with('success','Job Application removed'); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /job-board/app/Http/Middleware/Authenticate.php: -------------------------------------------------------------------------------- 1 | expectsJson() ? null : route('login'); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /job-board/app/Http/Middleware/EncryptCookies.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /job-board/app/Http/Middleware/PreventRequestsDuringMaintenance.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /job-board/app/Http/Middleware/RedirectIfAuthenticated.php: -------------------------------------------------------------------------------- 1 | check()) { 24 | return redirect(RouteServiceProvider::HOME); 25 | } 26 | } 27 | 28 | return $next($request); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /job-board/app/Http/Middleware/TrimStrings.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | 'current_password', 16 | 'password', 17 | 'password_confirmation', 18 | ]; 19 | } 20 | -------------------------------------------------------------------------------- /job-board/app/Http/Middleware/TrustHosts.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | public function hosts(): array 15 | { 16 | return [ 17 | $this->allSubdomainsOfApplicationUrl(), 18 | ]; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /job-board/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 | -------------------------------------------------------------------------------- /job-board/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 | -------------------------------------------------------------------------------- /job-board/app/Http/Middleware/VerifyCsrfToken.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /job-board/app/Models/Employer.php: -------------------------------------------------------------------------------- 1 | hasMany(Job::class); 17 | } 18 | 19 | public function user():BelongsTo 20 | { 21 | return $this->belongsTo(User::class); 22 | } 23 | 24 | 25 | } 26 | -------------------------------------------------------------------------------- /job-board/app/Models/JobApplication.php: -------------------------------------------------------------------------------- 1 | belongsTo(Job::class); 20 | } 21 | 22 | public function user():BelongsTo 23 | { 24 | return $this->belongsTo(User::class); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /job-board/app/Models/User.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | protected $fillable = [ 23 | 'name', 24 | 'email', 25 | 'password', 26 | ]; 27 | 28 | /** 29 | * The attributes that should be hidden for serialization. 30 | * 31 | * @var array 32 | */ 33 | protected $hidden = [ 34 | 'password', 35 | 'remember_token', 36 | ]; 37 | 38 | /** 39 | * The attributes that should be cast. 40 | * 41 | * @var array 42 | */ 43 | protected $casts = [ 44 | 'email_verified_at' => 'datetime', 45 | 'password' => 'hashed', 46 | ]; 47 | 48 | 49 | public function employer():HasOne 50 | { 51 | return $this->hasOne(Employer::class); 52 | } 53 | 54 | public function jobApplication():HasMany 55 | { 56 | return $this->hasMany(JobApplication::class); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /job-board/app/Providers/AppServiceProvider.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | protected $policies = [ 16 | // 17 | ]; 18 | 19 | /** 20 | * Register any authentication / authorization services. 21 | */ 22 | public function boot(): void 23 | { 24 | // 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /job-board/app/Providers/BroadcastServiceProvider.php: -------------------------------------------------------------------------------- 1 | > 16 | */ 17 | protected $listen = [ 18 | Registered::class => [ 19 | SendEmailVerificationNotification::class, 20 | ], 21 | ]; 22 | 23 | /** 24 | * Register any events for your application. 25 | */ 26 | 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 | -------------------------------------------------------------------------------- /job-board/app/Providers/RouteServiceProvider.php: -------------------------------------------------------------------------------- 1 | by($request->user()?->id ?: $request->ip()); 29 | }); 30 | 31 | $this->routes(function () { 32 | Route::middleware('api') 33 | ->prefix('api') 34 | ->group(base_path('routes/api.php')); 35 | 36 | Route::middleware('web') 37 | ->group(base_path('routes/web.php')); 38 | }); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /job-board/app/View/Components/Breadcrumbs.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 | -------------------------------------------------------------------------------- /job-board/config/services.php: -------------------------------------------------------------------------------- 1 | [ 18 | 'domain' => env('MAILGUN_DOMAIN'), 19 | 'secret' => env('MAILGUN_SECRET'), 20 | 'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'), 21 | 'scheme' => 'https', 22 | ], 23 | 24 | 'postmark' => [ 25 | 'token' => env('POSTMARK_TOKEN'), 26 | ], 27 | 28 | 'ses' => [ 29 | 'key' => env('AWS_ACCESS_KEY_ID'), 30 | 'secret' => env('AWS_SECRET_ACCESS_KEY'), 31 | 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), 32 | ], 33 | 34 | ]; 35 | -------------------------------------------------------------------------------- /job-board/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 | -------------------------------------------------------------------------------- /job-board/database/.gitignore: -------------------------------------------------------------------------------- 1 | *.sqlite* 2 | -------------------------------------------------------------------------------- /job-board/database/factories/EmployerFactory.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class EmployerFactory extends Factory 11 | { 12 | /** 13 | * Define the model's default state. 14 | * 15 | * @return array 16 | */ 17 | public function definition(): array 18 | { 19 | return [ 20 | 'company_name' => fake()->company 21 | ]; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /job-board/database/factories/JobApplicationFactory.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class JobApplicationFactory extends Factory 11 | { 12 | /** 13 | * Define the model's default state. 14 | * 15 | * @return array 16 | */ 17 | public function definition(): array 18 | { 19 | return [ 20 | 'expected_salary'=>fake()->numberBetween(4_000,170_000) 21 | ]; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /job-board/database/factories/JobFactory.php: -------------------------------------------------------------------------------- 1 | 10 | */ 11 | class JobFactory 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 | 'title' => fake()->jobTitle, 22 | 'description' => fake()->paragraphs(3,true), 23 | 'salary' => fake()->numberBetween(5_000,150_000), 24 | 'location'=>fake()->city, 25 | 'category'=> fake()->randomElement(Job::$category), 26 | 'experience'=> fake()->randomElement(Job::$experience), 27 | ]; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /job-board/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 | -------------------------------------------------------------------------------- /job-board/database/migrations/2014_10_12_000000_create_users_table.php: -------------------------------------------------------------------------------- 1 | id(); 16 | $table->string('name'); 17 | $table->string('email')->unique(); 18 | $table->timestamp('email_verified_at')->nullable(); 19 | $table->string('password'); 20 | $table->rememberToken(); 21 | $table->timestamps(); 22 | }); 23 | } 24 | 25 | /** 26 | * Reverse the migrations. 27 | */ 28 | public function down(): void 29 | { 30 | Schema::dropIfExists('users'); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /job-board/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 | -------------------------------------------------------------------------------- /job-board/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 | -------------------------------------------------------------------------------- /job-board/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 | -------------------------------------------------------------------------------- /job-board/database/migrations/2023_09_07_210714_create_jobs_table.php: -------------------------------------------------------------------------------- 1 | id(); 17 | $table->string('title'); 18 | $table->text('description'); 19 | $table->unsignedInteger('salary'); 20 | $table->string('location'); 21 | $table->string('category'); 22 | $table->enum('experience',Job::$experience); 23 | $table->timestamps(); 24 | }); 25 | } 26 | 27 | /** 28 | * Reverse the migrations. 29 | */ 30 | public function down(): void 31 | { 32 | Schema::dropIfExists('jobs'); 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /job-board/database/migrations/2023_09_22_213945_create_employers_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->string('company_name'); 19 | $table->foreignIdFor(User::class)->nullable()->constrained(); 20 | $table->timestamps(); 21 | }); 22 | 23 | Schema::table('jobs',function(Blueprint $table){ 24 | $table->foreignIdFor(Employer::class)->constrained(); 25 | }); 26 | } 27 | 28 | /** 29 | * Reverse the migrations. 30 | */ 31 | public function down(): void 32 | { 33 | Schema::table('jobs',function(Blueprint $table){ 34 | $table->dropForeignIdFor(Employer::class); 35 | }); 36 | Schema::dropIfExists('employers'); 37 | } 38 | }; 39 | -------------------------------------------------------------------------------- /job-board/database/migrations/2023_09_24_183103_create_job_applications_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->foreignIdFor(User::class)->constrained(); 19 | $table->foreignIdFor(Job::class)->constrained(); 20 | $table->unsignedInteger('expected_salary'); 21 | $table->timestamps(); 22 | }); 23 | } 24 | 25 | /** 26 | * Reverse the migrations. 27 | */ 28 | public function down(): void 29 | { 30 | Schema::dropIfExists('job_applications'); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /job-board/database/migrations/2023_09_26_173615_add_cv_path_to_job_applications_table.php: -------------------------------------------------------------------------------- 1 | string('cv_path')->nullable(); 16 | 17 | }); 18 | } 19 | 20 | /** 21 | * Reverse the migrations. 22 | */ 23 | public function down(): void 24 | { 25 | Schema::table('job_applications', function (Blueprint $table) { 26 | $table->dropColumn('cv_path'); 27 | }); 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /job-board/database/seeders/DatabaseSeeder.php: -------------------------------------------------------------------------------- 1 | create(); 21 | 22 | \App\Models\User::factory()->create([ 23 | 'name' => 'Moemen Saadeh', 24 | 'email' => 'moemensaadeh5@gmail.com', 25 | ]); 26 | 27 | User::factory(300)->create(); 28 | $users=User::all()->shuffle(); 29 | for($i=0;$i<20;$i++){ 30 | Employer::factory()->create([ 31 | 'user_id' => $users->pop()->id 32 | ]); 33 | } 34 | 35 | $employers = Employer::all(); 36 | 37 | for($i=0;$i<100;$i++){ 38 | Job::factory()->create([ 39 | 'employer_id' => $employers->random()->id 40 | ]); 41 | } 42 | 43 | 44 | foreach($users as $user){ 45 | $jobs= Job::inRandomOrder()->take(rand(0,4))->get(); 46 | 47 | foreach($jobs as $job){ 48 | JobApplication::factory()->create([ 49 | 'job_id' => $job->id, 50 | 'user_id' => $user->id 51 | ]); 52 | } 53 | } 54 | 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /job-board/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "type": "module", 4 | "scripts": { 5 | "dev": "vite", 6 | "build": "vite build" 7 | }, 8 | "devDependencies": { 9 | "@tailwindcss/forms": "^0.5.6", 10 | "autoprefixer": "^10.4.15", 11 | "axios": "^1.1.2", 12 | "laravel-vite-plugin": "^0.8.0", 13 | "postcss": "^8.4.29", 14 | "tailwindcss": "^3.3.3", 15 | "vite": "^4.0.0" 16 | }, 17 | "dependencies": { 18 | "alpinejs": "^3.13.0" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /job-board/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 | -------------------------------------------------------------------------------- /job-board/postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /job-board/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 | -------------------------------------------------------------------------------- /job-board/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moemen12/laravel-projects/6e6181d69cbb59fb1e01b9c87044bb687f375fd4/job-board/public/favicon.ico -------------------------------------------------------------------------------- /job-board/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /job-board/resources/css/app.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; -------------------------------------------------------------------------------- /job-board/resources/js/app.js: -------------------------------------------------------------------------------- 1 | import './bootstrap'; 2 | 3 | -------------------------------------------------------------------------------- /job-board/resources/js/bootstrap.js: -------------------------------------------------------------------------------- 1 | /** 2 | * We'll load the axios HTTP library which allows us to easily issue requests 3 | * to our Laravel back-end. This library automatically handles sending the 4 | * CSRF token as a header based on the value of the "XSRF" token cookie. 5 | */ 6 | 7 | import axios from 'axios'; 8 | import Alpine from 'alpinejs' 9 | window.axios = axios; 10 | 11 | window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; 12 | 13 | 14 | 15 | window.Alpine = Alpine 16 | 17 | Alpine.start() -------------------------------------------------------------------------------- /job-board/resources/views/auth/create.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Sign in to your account

4 | 5 | 6 |
7 | @csrf 8 | 9 |
10 | E-mail 11 | 12 |
13 | 14 |
15 | Password 16 | 17 |
18 | 19 | 20 |
21 |
22 |
23 | 24 | 25 |
26 |
27 |
28 | Forget password? 29 |
30 |
31 | 32 | 33 | Login 34 | 35 | 36 |
37 |
38 |
-------------------------------------------------------------------------------- /job-board/resources/views/components/breadcrumbs.blade.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /job-board/resources/views/components/button.blade.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /job-board/resources/views/components/card.blade.php: -------------------------------------------------------------------------------- 1 |
class(['rounded-md border border-slate-300 bg-white p-4 shadow-sm']) }}> 2 | {{ $slot }} 3 |
-------------------------------------------------------------------------------- /job-board/resources/views/components/job-card.blade.php: -------------------------------------------------------------------------------- 1 | 2 |
3 |

{{ $job->title }}

4 |
5 | ${{ number_format($job->salary) }} 6 |
7 |
8 | 9 |
10 |
11 |
{{ $job->employer->company_name }}
12 |
{{ $job->location }}
13 |
14 | 28 |
29 | 30 | 31 | {{ $slot }} 32 |
-------------------------------------------------------------------------------- /job-board/resources/views/components/label.blade.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /job-board/resources/views/components/link-button.blade.php: -------------------------------------------------------------------------------- 1 | 5 | {{ $slot }} 6 | 7 | -------------------------------------------------------------------------------- /job-board/resources/views/components/radio-group.blade.php: -------------------------------------------------------------------------------- 1 |
2 | 6 | 7 | @foreach ($options as $option) 8 | 13 | @endforeach 14 |
-------------------------------------------------------------------------------- /job-board/resources/views/components/tag.blade.php: -------------------------------------------------------------------------------- 1 |
{{ $slot }}
-------------------------------------------------------------------------------- /job-board/resources/views/job/show.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 |

10 | {!! nl2br(e($job->description)) !!} 11 |

12 | 13 | 14 | @can('apply', $job) 15 | 16 | Apply 17 | 18 | @else 19 |
You already applied to this job
20 | @endcan 21 |
22 | 23 | 24 |

25 | More {{ $job->employer->company_name }} Jobs 26 |

27 | 28 |
29 | @foreach ($job->employer->jobs as $otherJob) 30 |
31 |
32 | 37 |
38 | {{ $otherJob->created_at->diffForHumans() }} 39 |
40 |
41 |
42 | ${{ number_format($otherJob->salary) }} 43 |
44 |
45 | @endforeach 46 |
47 |
48 |
-------------------------------------------------------------------------------- /job-board/resources/views/job_application/create.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 |

15 | Your Job Application 16 |

17 |
18 | @csrf 19 |
20 | Expected Salary 21 | 22 |
23 | 24 |
25 | Upload CV 26 | 27 |
28 | 29 | 30 | Apply 31 |
32 |
33 |
34 | -------------------------------------------------------------------------------- /job-board/routes/api.php: -------------------------------------------------------------------------------- 1 | get('/user', function (Request $request) { 18 | return $request->user(); 19 | }); 20 | -------------------------------------------------------------------------------- /job-board/routes/channels.php: -------------------------------------------------------------------------------- 1 | id === (int) $id; 18 | }); 19 | -------------------------------------------------------------------------------- /job-board/routes/console.php: -------------------------------------------------------------------------------- 1 | comment(Inspiring::quote()); 19 | })->purpose('Display an inspiring quote'); 20 | -------------------------------------------------------------------------------- /job-board/routes/web.php: -------------------------------------------------------------------------------- 1 | to_route('jobs.index')); 22 | 23 | Route::resource('jobs', JobController::class) 24 | ->only(['index', 'show']); 25 | 26 | Route::get('login', fn() => to_route('auth.create'))->name('login'); 27 | Route::resource('auth', AuthController::class) 28 | ->only(['create', 'store']); 29 | Route::delete('logout', fn() => to_route('auth.destroy'))->name('logout'); 30 | Route::delete('auth', [AuthController::class, 'destroy']) 31 | ->name('auth.destroy'); 32 | 33 | Route::middleware('auth')->group(function () { 34 | Route::resource('job.application', JobApplicationController::class) 35 | ->only(['create', 'store']); 36 | Route::resource('my-job-applications',MyJobApplicationController::class)->only(['index','destroy']); 37 | 38 | }); -------------------------------------------------------------------------------- /job-board/storage/app/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !public/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /job-board/storage/app/public/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /job-board/storage/debugbar/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /job-board/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 | -------------------------------------------------------------------------------- /job-board/storage/framework/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !data/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /job-board/storage/framework/cache/data/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /job-board/storage/framework/sessions/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /job-board/storage/framework/testing/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /job-board/storage/framework/views/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /job-board/storage/logs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /job-board/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | export default { 3 | content: [ 4 | "./resources/**/*.blade.php", 5 | "./resources/**/*.js", 6 | "./resources/**/*.vue", 7 | ], 8 | theme: { 9 | extend: {}, 10 | }, 11 | plugins: [ 12 | require('@tailwindcss/forms') 13 | ], 14 | } 15 | 16 | -------------------------------------------------------------------------------- /job-board/tests/CreatesApplication.php: -------------------------------------------------------------------------------- 1 | make(Kernel::class)->bootstrap(); 18 | 19 | return $app; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /job-board/tests/Feature/ExampleTest.php: -------------------------------------------------------------------------------- 1 | get('/'); 16 | 17 | $response->assertStatus(200); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /job-board/tests/TestCase.php: -------------------------------------------------------------------------------- 1 | assertTrue(true); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /job-board/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import laravel from 'laravel-vite-plugin'; 3 | 4 | export default defineConfig({ 5 | plugins: [ 6 | laravel({ 7 | input: ['resources/css/app.css', 'resources/js/app.js'], 8 | refresh: true, 9 | }), 10 | ], 11 | }); 12 | -------------------------------------------------------------------------------- /livewire-poll/.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 = true 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 | -------------------------------------------------------------------------------- /livewire-poll/.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_APP_NAME="${APP_NAME}" 55 | VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}" 56 | VITE_PUSHER_HOST="${PUSHER_HOST}" 57 | VITE_PUSHER_PORT="${PUSHER_PORT}" 58 | VITE_PUSHER_SCHEME="${PUSHER_SCHEME}" 59 | VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" 60 | -------------------------------------------------------------------------------- /livewire-poll/.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 | -------------------------------------------------------------------------------- /livewire-poll/.gitignore: -------------------------------------------------------------------------------- 1 | /.phpunit.cache 2 | /node_modules 3 | /public/build 4 | /public/hot 5 | /public/storage 6 | /storage/*.key 7 | /vendor 8 | .env 9 | .env.backup 10 | .env.production 11 | .phpunit.result.cache 12 | Homestead.json 13 | Homestead.yaml 14 | auth.json 15 | npm-debug.log 16 | yarn-error.log 17 | /.fleet 18 | /.idea 19 | /.vscode 20 | -------------------------------------------------------------------------------- /livewire-poll/app/Console/Kernel.php: -------------------------------------------------------------------------------- 1 | command('inspire')->hourly(); 16 | } 17 | 18 | /** 19 | * Register the commands for the application. 20 | */ 21 | protected function commands(): void 22 | { 23 | $this->load(__DIR__.'/Commands'); 24 | 25 | require base_path('routes/console.php'); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /livewire-poll/app/Exceptions/Handler.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | protected $dontFlash = [ 16 | 'current_password', 17 | 'password', 18 | 'password_confirmation', 19 | ]; 20 | 21 | /** 22 | * Register the exception handling callbacks for the application. 23 | */ 24 | public function register(): void 25 | { 26 | $this->reportable(function (Throwable $e) { 27 | // 28 | }); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /livewire-poll/app/Http/Controllers/Controller.php: -------------------------------------------------------------------------------- 1 | 'render' 14 | ]; 15 | 16 | public function render() 17 | { 18 | 19 | $polls = Poll::with('options.votes')->latest()->get(); 20 | return view('livewire.polls',['polls'=> $polls]); 21 | } 22 | 23 | public function vote(Option $option){ 24 | $option->votes()->create(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /livewire-poll/app/Http/Middleware/Authenticate.php: -------------------------------------------------------------------------------- 1 | expectsJson() ? null : route('login'); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /livewire-poll/app/Http/Middleware/EncryptCookies.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /livewire-poll/app/Http/Middleware/PreventRequestsDuringMaintenance.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /livewire-poll/app/Http/Middleware/RedirectIfAuthenticated.php: -------------------------------------------------------------------------------- 1 | check()) { 24 | return redirect(RouteServiceProvider::HOME); 25 | } 26 | } 27 | 28 | return $next($request); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /livewire-poll/app/Http/Middleware/TrimStrings.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | 'current_password', 16 | 'password', 17 | 'password_confirmation', 18 | ]; 19 | } 20 | -------------------------------------------------------------------------------- /livewire-poll/app/Http/Middleware/TrustHosts.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | public function hosts(): array 15 | { 16 | return [ 17 | $this->allSubdomainsOfApplicationUrl(), 18 | ]; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /livewire-poll/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 | -------------------------------------------------------------------------------- /livewire-poll/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 | -------------------------------------------------------------------------------- /livewire-poll/app/Http/Middleware/VerifyCsrfToken.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /livewire-poll/app/Models/Option.php: -------------------------------------------------------------------------------- 1 | belongsTo(Poll::class); 18 | } 19 | 20 | public function votes(): HasMany 21 | { 22 | return $this->hasMany(Vote::class); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /livewire-poll/app/Models/Poll.php: -------------------------------------------------------------------------------- 1 | hasMany(Option::class); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /livewire-poll/app/Models/User.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | protected $fillable = [ 21 | 'name', 22 | 'email', 23 | 'password', 24 | ]; 25 | 26 | /** 27 | * The attributes that should be hidden for serialization. 28 | * 29 | * @var array 30 | */ 31 | protected $hidden = [ 32 | 'password', 33 | 'remember_token', 34 | ]; 35 | 36 | /** 37 | * The attributes that should be cast. 38 | * 39 | * @var array 40 | */ 41 | protected $casts = [ 42 | 'email_verified_at' => 'datetime', 43 | 'password' => 'hashed', 44 | ]; 45 | } 46 | -------------------------------------------------------------------------------- /livewire-poll/app/Models/Vote.php: -------------------------------------------------------------------------------- 1 | belongsTo(Option::class); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /livewire-poll/app/Providers/AppServiceProvider.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | protected $policies = [ 16 | // 17 | ]; 18 | 19 | /** 20 | * Register any authentication / authorization services. 21 | */ 22 | public function boot(): void 23 | { 24 | // 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /livewire-poll/app/Providers/BroadcastServiceProvider.php: -------------------------------------------------------------------------------- 1 | > 16 | */ 17 | protected $listen = [ 18 | Registered::class => [ 19 | SendEmailVerificationNotification::class, 20 | ], 21 | ]; 22 | 23 | /** 24 | * Register any events for your application. 25 | */ 26 | 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 | -------------------------------------------------------------------------------- /livewire-poll/app/Providers/RouteServiceProvider.php: -------------------------------------------------------------------------------- 1 | by($request->user()?->id ?: $request->ip()); 29 | }); 30 | 31 | $this->routes(function () { 32 | Route::middleware('api') 33 | ->prefix('api') 34 | ->group(base_path('routes/api.php')); 35 | 36 | Route::middleware('web') 37 | ->group(base_path('routes/web.php')); 38 | }); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /livewire-poll/bootstrap/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /livewire-poll/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 | -------------------------------------------------------------------------------- /livewire-poll/config/services.php: -------------------------------------------------------------------------------- 1 | [ 18 | 'domain' => env('MAILGUN_DOMAIN'), 19 | 'secret' => env('MAILGUN_SECRET'), 20 | 'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'), 21 | 'scheme' => 'https', 22 | ], 23 | 24 | 'postmark' => [ 25 | 'token' => env('POSTMARK_TOKEN'), 26 | ], 27 | 28 | 'ses' => [ 29 | 'key' => env('AWS_ACCESS_KEY_ID'), 30 | 'secret' => env('AWS_SECRET_ACCESS_KEY'), 31 | 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), 32 | ], 33 | 34 | ]; 35 | -------------------------------------------------------------------------------- /livewire-poll/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 | -------------------------------------------------------------------------------- /livewire-poll/database/.gitignore: -------------------------------------------------------------------------------- 1 | *.sqlite* 2 | -------------------------------------------------------------------------------- /livewire-poll/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 | -------------------------------------------------------------------------------- /livewire-poll/database/migrations/2014_10_12_000000_create_users_table.php: -------------------------------------------------------------------------------- 1 | id(); 16 | $table->string('name'); 17 | $table->string('email')->unique(); 18 | $table->timestamp('email_verified_at')->nullable(); 19 | $table->string('password'); 20 | $table->rememberToken(); 21 | $table->timestamps(); 22 | }); 23 | } 24 | 25 | /** 26 | * Reverse the migrations. 27 | */ 28 | public function down(): void 29 | { 30 | Schema::dropIfExists('users'); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /livewire-poll/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 | -------------------------------------------------------------------------------- /livewire-poll/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 | -------------------------------------------------------------------------------- /livewire-poll/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 | -------------------------------------------------------------------------------- /livewire-poll/database/migrations/2023_09_04_010105_create_polls_table.php: -------------------------------------------------------------------------------- 1 | id(); 16 | $table->string('title'); 17 | $table->timestamps(); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | */ 24 | public function down(): void 25 | { 26 | Schema::dropIfExists('polls'); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /livewire-poll/database/migrations/2023_09_04_010155_create_options_table.php: -------------------------------------------------------------------------------- 1 | id(); 17 | $table->string('name'); 18 | $table->timestamps(); 19 | $table->foreignIdFor(Poll::class)->constrained(); 20 | }); 21 | } 22 | 23 | /** 24 | * Reverse the migrations. 25 | */ 26 | public function down(): void 27 | { 28 | Schema::dropIfExists('options'); 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /livewire-poll/database/migrations/2023_09_04_010156_create_votes_table.php: -------------------------------------------------------------------------------- 1 | id(); 17 | $table->timestamps(); 18 | $table->foreignIdFor(Option::class)->constrained(); 19 | }); 20 | } 21 | 22 | /** 23 | * Reverse the migrations. 24 | */ 25 | public function down(): void 26 | { 27 | Schema::dropIfExists('votes'); 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /livewire-poll/database/seeders/DatabaseSeeder.php: -------------------------------------------------------------------------------- 1 | create(); 16 | 17 | // \App\Models\User::factory()->create([ 18 | // 'name' => 'Test User', 19 | // 'email' => 'test@example.com', 20 | // ]); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /livewire-poll/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "type": "module", 4 | "scripts": { 5 | "dev": "vite", 6 | "build": "vite build" 7 | }, 8 | "devDependencies": { 9 | "axios": "^1.1.2", 10 | "laravel-vite-plugin": "^0.8.0", 11 | "vite": "^4.0.0" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /livewire-poll/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 | -------------------------------------------------------------------------------- /livewire-poll/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 | -------------------------------------------------------------------------------- /livewire-poll/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moemen12/laravel-projects/6e6181d69cbb59fb1e01b9c87044bb687f375fd4/livewire-poll/public/favicon.ico -------------------------------------------------------------------------------- /livewire-poll/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /livewire-poll/resources/css/app.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moemen12/laravel-projects/6e6181d69cbb59fb1e01b9c87044bb687f375fd4/livewire-poll/resources/css/app.css -------------------------------------------------------------------------------- /livewire-poll/resources/js/app.js: -------------------------------------------------------------------------------- 1 | import './bootstrap'; 2 | -------------------------------------------------------------------------------- /livewire-poll/resources/js/bootstrap.js: -------------------------------------------------------------------------------- 1 | /** 2 | * We'll load the axios HTTP library which allows us to easily issue requests 3 | * to our Laravel back-end. This library automatically handles sending the 4 | * CSRF token as a header based on the value of the "XSRF" token cookie. 5 | */ 6 | 7 | import axios from 'axios'; 8 | window.axios = axios; 9 | 10 | window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; 11 | 12 | /** 13 | * Echo exposes an expressive API for subscribing to channels and listening 14 | * for events that are broadcast by Laravel. Echo and event broadcasting 15 | * allows your team to easily build robust real-time web applications. 16 | */ 17 | 18 | // import Echo from 'laravel-echo'; 19 | 20 | // import Pusher from 'pusher-js'; 21 | // window.Pusher = Pusher; 22 | 23 | // window.Echo = new Echo({ 24 | // broadcaster: 'pusher', 25 | // key: import.meta.env.VITE_PUSHER_APP_KEY, 26 | // cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER ?? 'mt1', 27 | // wsHost: import.meta.env.VITE_PUSHER_HOST ? import.meta.env.VITE_PUSHER_HOST : `ws-${import.meta.env.VITE_PUSHER_APP_CLUSTER}.pusher.com`, 28 | // wsPort: import.meta.env.VITE_PUSHER_PORT ?? 80, 29 | // wssPort: import.meta.env.VITE_PUSHER_PORT ?? 443, 30 | // forceTLS: (import.meta.env.VITE_PUSHER_SCHEME ?? 'https') === 'https', 31 | // enabledTransports: ['ws', 'wss'], 32 | // }); 33 | -------------------------------------------------------------------------------- /livewire-poll/resources/views/app.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Laravel Livewire Poll 8 | 9 | 10 | 11 | {{-- blade-formatter-disable --}} 12 | 27 | {{-- blade-formatter-enable --}} 28 | 29 | @livewireStyles 30 | 31 | 32 | 33 | 34 |
35 |

Create Poll

36 | @livewire('create-poll') 37 |
38 | 39 | 40 | 41 |
42 |

Available Polls

43 | @livewire('polls') 44 |
45 | 46 | 47 | 48 | @livewireScripts 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /livewire-poll/resources/views/livewire/create-poll.blade.php: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 | 6 | 7 | 8 | @error('title') 9 |
{{ $message }}
10 | @enderror 11 | 12 |
13 |
Add Option
14 |
15 | 16 |
17 | @foreach ($options as $index => $option) 18 |
19 | 20 | 21 |
22 | 23 | 24 |
25 | @error("options.{$index}") 26 |
{{ $message }}
27 | @enderror 28 |
29 | 30 | 31 | @endforeach 32 |
33 | 34 | 35 |
36 | 37 |
38 | -------------------------------------------------------------------------------- /livewire-poll/resources/views/livewire/polls.blade.php: -------------------------------------------------------------------------------- 1 |
2 | @forelse ($polls as $poll) 3 |
4 |

{{ $poll->title }}

5 | 6 | @foreach ($poll->options as $option) 7 |
8 | 9 | {{ $option->name }} {{ $option->votes->count() }} 10 |
11 | @endforeach 12 |
13 | @empty 14 |
No polls available !
15 | @endforelse 16 |
17 | -------------------------------------------------------------------------------- /livewire-poll/routes/api.php: -------------------------------------------------------------------------------- 1 | get('/user', function (Request $request) { 18 | return $request->user(); 19 | }); 20 | -------------------------------------------------------------------------------- /livewire-poll/routes/channels.php: -------------------------------------------------------------------------------- 1 | id === (int) $id; 18 | }); 19 | -------------------------------------------------------------------------------- /livewire-poll/routes/console.php: -------------------------------------------------------------------------------- 1 | comment(Inspiring::quote()); 19 | })->purpose('Display an inspiring quote'); 20 | -------------------------------------------------------------------------------- /livewire-poll/routes/web.php: -------------------------------------------------------------------------------- 1 | make(Kernel::class)->bootstrap(); 18 | 19 | return $app; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /livewire-poll/tests/Feature/ExampleTest.php: -------------------------------------------------------------------------------- 1 | get('/'); 16 | 17 | $response->assertStatus(200); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /livewire-poll/tests/TestCase.php: -------------------------------------------------------------------------------- 1 | assertTrue(true); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /livewire-poll/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import laravel from 'laravel-vite-plugin'; 3 | 4 | export default defineConfig({ 5 | plugins: [ 6 | laravel({ 7 | input: ['resources/css/app.css', 'resources/js/app.js'], 8 | refresh: true, 9 | }), 10 | ], 11 | }); 12 | --------------------------------------------------------------------------------