├── .editorconfig
├── .env.example
├── .gitattributes
├── .gitignore
├── README.md
├── _theme_files
├── create-job.html
├── css
│ └── style.css
├── dashboard.html
├── error.html
├── images
│ ├── default-avatar.png
│ ├── hero.jpg
│ └── logos
│ │ ├── logo-algorix.png
│ │ ├── logo-bitwave.png
│ │ ├── logo-digital-media.png
│ │ ├── logo-nextgen.png
│ │ ├── logo-pink-pig.png
│ │ ├── logo-quantumcode.png
│ │ ├── logo-shield.png
│ │ ├── logo-sparkle.png
│ │ ├── logo-tec-solutions.png
│ │ ├── logo-vencom.png
│ │ └── logos.psd
├── index.html
├── job-details.html
├── job_listings.php
├── jobs.html
├── js
│ └── script.js
├── login.html
├── register.html
└── saved-jobs.html
├── app
├── Http
│ ├── Controllers
│ │ ├── ApplicantController.php
│ │ ├── BookmarkController.php
│ │ ├── Controller.php
│ │ ├── DashboardController.php
│ │ ├── GeocodeController.php
│ │ ├── HomeController.php
│ │ ├── JobController.php
│ │ ├── LoginController.php
│ │ ├── ProfileController.php
│ │ └── RegisterController.php
│ └── Middleware
│ │ └── LogRequest.php
├── Mail
│ └── JobApplied.php
├── Models
│ ├── Applicant.php
│ ├── Job.php
│ └── User.php
├── Policies
│ └── JobPolicy.php
├── Providers
│ ├── AppServiceProvider.php
│ └── AuthServiceProvider.php
└── View
│ └── Components
│ ├── Alert.php
│ ├── BottomBanner.php
│ ├── ButtonLink.php
│ ├── File.php
│ ├── Header.php
│ ├── Hero.php
│ ├── JobCard.php
│ ├── Layout.php
│ ├── LogoutButton.php
│ ├── NavLink.php
│ ├── Search.php
│ ├── Select.php
│ ├── Text.php
│ ├── TextArea.php
│ └── TopBanner.php
├── artisan
├── bootstrap
├── app.php
├── cache
│ └── .gitignore
└── providers.php
├── composer.json
├── composer.lock
├── config
├── app.php
├── auth.php
├── cache.php
├── database.php
├── filesystems.php
├── logging.php
├── mail.php
├── queue.php
├── services.php
└── session.php
├── database
├── .gitignore
├── factories
│ ├── JobFactory.php
│ └── UserFactory.php
├── migrations
│ ├── 0001_01_01_000000_create_users_table.php
│ ├── 0001_01_01_000001_create_cache_table.php
│ ├── 0001_01_01_000002_create_jobs_table.php
│ ├── 2024_09_11_172954_create_job_listings_table.php
│ ├── 2024_09_12_120240_add_fields_to_job_listings_table.php
│ ├── 2024_09_16_134742_add_avatar_to_users_table.php
│ ├── 2024_09_16_180928_create_job_user_bookmarks_table.php
│ └── 2024_09_17_130558_create_applicants_table.php
└── seeders
│ ├── BookmarkSeeder.php
│ ├── DatabaseSeeder.php
│ ├── JobSeeder.php
│ ├── RandomJobSeeder.php
│ ├── RandomUserSeeder.php
│ ├── TestUserSeeder.php
│ └── data
│ └── job_listings.php
├── package-lock.json
├── package.json
├── phpunit.xml
├── postcss.config.js
├── public
├── .DS_Store
├── .htaccess
├── css
│ └── style.css
├── favicon.ico
├── images
│ ├── hero.jpg
│ ├── logos
│ │ ├── logo-algorix.png
│ │ ├── logo-bitwave.png
│ │ ├── logo-digital-media.png
│ │ ├── logo-nextgen.png
│ │ ├── logo-pink-pig.png
│ │ ├── logo-quantumcode.png
│ │ ├── logo-shield.png
│ │ ├── logo-sparkle.png
│ │ ├── logo-tec-solutions.png
│ │ ├── logo-vencom.png
│ │ └── logos.psd
│ └── screen.png
├── index.php
├── js
│ └── script.js
└── robots.txt
├── resources
├── css
│ └── app.css
├── js
│ ├── app.js
│ └── bootstrap.js
└── views
│ ├── auth
│ ├── login.blade.php
│ └── register.blade.php
│ ├── components
│ ├── alert.blade.php
│ ├── bottom-banner.blade.php
│ ├── button-link.blade.php
│ ├── header.blade.php
│ ├── hero.blade.php
│ ├── inputs
│ │ ├── file.blade.php
│ │ ├── select.blade.php
│ │ ├── text-area.blade.php
│ │ └── text.blade.php
│ ├── job-card.blade.php
│ ├── logout-button.blade.php
│ ├── nav-link.blade.php
│ ├── search.blade.php
│ └── top-banner.blade.php
│ ├── dashboard
│ └── index.blade.php
│ ├── emails
│ └── job-applied.blade.php
│ ├── jobs
│ ├── bookmarked.blade.php
│ ├── create.blade.php
│ ├── edit.blade.php
│ ├── index.blade.php
│ └── show.blade.php
│ ├── layout.blade.php
│ ├── pages
│ └── index.blade.php
│ └── vendor
│ └── pagination
│ ├── bootstrap-4.blade.php
│ ├── bootstrap-5.blade.php
│ ├── default.blade.php
│ ├── semantic-ui.blade.php
│ ├── simple-bootstrap-4.blade.php
│ ├── simple-bootstrap-5.blade.php
│ ├── simple-default.blade.php
│ ├── simple-tailwind.blade.php
│ └── tailwind.blade.php
├── routes
├── console.php
└── web.php
├── storage
├── app
│ ├── .gitignore
│ └── public
│ │ ├── .gitignore
│ │ ├── avatars
│ │ ├── OkN9SVc5zdTsaWcaG0bM312gkHEePc0PtGPK4op0.jpg
│ │ ├── WiOWwM95W5lsaPhv5UhYCLfXy2c6PDIGZuvqQStG.jpg
│ │ ├── default-avatar.png
│ │ └── eddYUMjw0De9RCrpH9YU003BVUpzqEtJievGakrU.jpg
│ │ ├── logos
│ │ ├── 8RcUlkmxJjXinPTfCzezE8mrAANdh33ErUflxD9K.png
│ │ ├── BKFdIXoacajQhfk1NHDGCoNnyBzSXzW38JPXLg42.png
│ │ ├── LCYGNDi5dUBrUTlfPZGj3csmjMwIqbfN0hpygJuR.png
│ │ ├── logo-algorix.png
│ │ ├── logo-bitwave.png
│ │ ├── logo-digital-media.png
│ │ ├── logo-nextgen.png
│ │ ├── logo-pink-pig.png
│ │ ├── logo-quantumcode.png
│ │ ├── logo-shield.png
│ │ ├── logo-sparkle.png
│ │ ├── logo-tec-solutions.png
│ │ ├── logo-vencom.png
│ │ └── n2L0rnB51Iw4Vvp8WYBLi22aAQvkPFHgEgWuqTSs.png
│ │ └── resumes
│ │ ├── 3TzIiBR3PDnGY0VhgAq5ZXbCQwb6q0euB25xOyDd.pdf
│ │ ├── 7F5vcwmHDo41Z9p0iOIxnn0nDAnfSM0iykeB20e3.pdf
│ │ ├── 93K9WFLAJ0j2UQNbYpUtyejtWzSD3ya3JjRJhecv.pdf
│ │ ├── LrtoqgDdoCgDk4mYmr6GapzARP5CfLqj9fZjkdi4.pdf
│ │ ├── XDJimgtfgUthXrdhD5IVH1ZwxkOVHqSFb71evoOA.pdf
│ │ ├── XxwMerVnDlLZkbnmAmj6XRMH4pKwlKyWswMKBkB8.pdf
│ │ ├── lGHyE9rmwUBwYcBvvOKMojtW4eOQZ8264aGDTkCk.pdf
│ │ ├── n42l6ugZp92OZcSIv9D8n9XkXcEhoF82LhN9zOXW.pdf
│ │ ├── nyY91fwL9WqQsIBo3CsuF5fTEkouGAMCpjLxMl44.pdf
│ │ └── vfJTz2m86HsmEVuAtkE3LL3SFkmgW3GsuHuxJbn3.pdf
├── framework
│ ├── .gitignore
│ ├── cache
│ │ ├── .gitignore
│ │ └── data
│ │ │ └── .gitignore
│ ├── sessions
│ │ └── .gitignore
│ ├── testing
│ │ └── .gitignore
│ └── views
│ │ └── .gitignore
└── logs
│ └── .gitignore
├── tailwind.config.js
├── tests
├── Feature
│ └── ExampleTest.php
├── TestCase.php
└── Unit
│ └── ExampleTest.php
└── vite.config.js
/.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 |
--------------------------------------------------------------------------------
/.env.example:
--------------------------------------------------------------------------------
1 | APP_NAME=Workopia
2 | APP_ENV=local
3 | APP_KEY=base64:g/j1T3xaJXTeYjPJJ5D5qWQr/YlCvL9Sl3TOmgXauVo=
4 | APP_DEBUG=true
5 | APP_TIMEZONE=UTC
6 | APP_URL=http://workopia.test
7 |
8 | APP_LOCALE=en
9 | APP_FALLBACK_LOCALE=en
10 | APP_FAKER_LOCALE=en_US
11 |
12 | APP_MAINTENANCE_DRIVER=file
13 | # APP_MAINTENANCE_STORE=database
14 |
15 | BCRYPT_ROUNDS=12
16 |
17 | LOG_CHANNEL=stack
18 | LOG_STACK=single
19 | LOG_DEPRECATIONS_CHANNEL=null
20 | LOG_LEVEL=debug
21 |
22 | DB_CONNECTION=pgsql
23 | DB_HOST=127.0.0.1
24 | DB_PORT=5432
25 | DB_DATABASE=YOUR_DATABASE_NAME
26 | DB_USERNAME=YOUR_DATABASE_USERNAME
27 | DB_PASSWORD=YOUR_DATABASE_PASSWORD
28 |
29 | SESSION_DRIVER=database
30 | SESSION_LIFETIME=120
31 | SESSION_ENCRYPT=false
32 | SESSION_PATH=/
33 | SESSION_DOMAIN=null
34 |
35 | BROADCAST_CONNECTION=log
36 | FILESYSTEM_DISK=local
37 | QUEUE_CONNECTION=database
38 |
39 | CACHE_STORE=database
40 | CACHE_PREFIX=
41 |
42 | MEMCACHED_HOST=127.0.0.1
43 |
44 | REDIS_CLIENT=phpredis
45 | REDIS_HOST=127.0.0.1
46 | REDIS_PASSWORD=null
47 | REDIS_PORT=6379
48 |
49 | MAIL_MAILER=smtp
50 | # MAIL_HOST=sandbox.smtp.mailtrap.io
51 | # MAIL_PORT=2525
52 | # MAIL_USERNAME=YOUR_USERNAME
53 | # MAIL_PASSWORD=YOUR_PASSWORD
54 | MAIL_HOST=live.smtp.mailtrap.io
55 | MAIL_PORT=587
56 | MAIL_USERNAME=api
57 | MAIL_PASSWORD=YOUR_PASSWORD
58 | MAIL_ENCRYPTION=null
59 | MAIL_FROM_ADDRESS="noreply@yourdomain.com"
60 | MAIL_FROM_NAME="${APP_NAME}"
61 |
62 | AWS_ACCESS_KEY_ID=
63 | AWS_SECRET_ACCESS_KEY=
64 | AWS_DEFAULT_REGION=us-east-1
65 | AWS_BUCKET=
66 | AWS_USE_PATH_STYLE_ENDPOINT=false
67 |
68 | VITE_APP_NAME="${APP_NAME}"
69 | MAPBOX_API_KEY=YOUR_API_KEY
70 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/.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 | .phpactor.json
12 | .phpunit.result.cache
13 | Homestead.json
14 | Homestead.yaml
15 | auth.json
16 | npm-debug.log
17 | yarn-error.log
18 | /.fleet
19 | /.idea
20 | /.vscode
21 | /.DS_Store
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Workopia (Laravel)
2 |
3 | Workopia is a job listing website built with Laravel 11. This is the main project from my Laravel From Scratch course.
4 |
5 | Course Link - https://www.traversymedia.com/laravel-from-scratch
6 |
7 |
8 |
9 | ## Features
10 |
11 | - Job Listing CRUD
12 | - Authentication & Authorization Policies
13 | - Profile Avatar Upload
14 | - Blade UI Components
15 | - Vite & Tailwind Integration
16 | - Bookmarking System
17 | - Apply & Upload Resume
18 | - User Dashboard
19 | - Alpine.js For Interactivity
20 | - Database Seeder
21 | - Job Search
22 | - Mapbox Maps
23 | - Mailers With Mailtrap
24 | - Job Listing Pagination
25 |
26 | ## Usage
27 |
28 | #### Install composer dependencies
29 |
30 | ```
31 | composer install
32 | ```
33 |
34 | #### Install NPM dependencies and build assets
35 |
36 | ```
37 | npm install
38 | npm run build
39 | ```
40 |
41 | #### Add .env Variables
42 |
43 | Rename the `.env.example` file to `.env` and add your database values. Change driver and port as needed.
44 |
45 | ```
46 | DB_CONNECTION=pgsql
47 | DB_HOST=127.0.0.1
48 | DB_PORT=5432
49 | DB_DATABASE=
50 | DB_USERNAME=
51 | DB_PASSWORD=
52 | ```
53 |
54 | Add your mabox API key:
55 |
56 | ```
57 | MAPBOX_API_KEY=
58 | ```
59 |
60 | #### Run Migrations
61 |
62 | ```
63 | php artisan migrate
64 | ```
65 |
66 | #### Seed Database (Optional)
67 |
68 | You can seed the database with users, jobs and bookmarks
69 |
70 | ```
71 | php artisan db:seed
72 | ```
73 |
74 | You will have a test user available with the following credentials:
75 |
76 | - Email: test@test.com
77 | - Password: 12345678
78 |
79 | #### Run Server
80 |
81 | If you are using artisan to serve, run the following:
82 |
83 | ```
84 | php artisan serve
85 | ```
86 |
87 | Open http://localhost:8000
88 |
89 | ## License
90 |
91 | Workopia has an open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).
92 |
--------------------------------------------------------------------------------
/_theme_files/css/style.css:
--------------------------------------------------------------------------------
1 | .overlay {
2 | position: absolute;
3 | top: 0;
4 | left: 0;
5 | width: 100%;
6 | height: 100%;
7 | background-color: rgba(0, 0, 0, 0.8); /* Adjust opacity as needed */
8 | z-index: 1;
9 | }
10 |
11 | .hero {
12 | background-image: url("../images/hero.jpg");
13 | }
14 |
--------------------------------------------------------------------------------
/_theme_files/error.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
105 | Discover the perfect job opportunity for you. 106 |
107 |118 | This page does not exist 119 |
120 |9 | {{$subheading}} 10 |
11 |{{$message}}
11 | @enderror 12 |{{$message}}
19 | @enderror 20 |{{$message}}
12 | @enderror 13 |{{$message}}
12 | @enderror 13 |{{$job->job_type}}
13 |16 | {{Str::limit($job->description, 100)}} 17 |
18 |9 | {{$subheading}} 10 |
11 |{{$job->job_type}}
40 |62 | Name: {{$applicant->full_name}} 63 |
64 |65 | Phone: {{$applicant->contact_phone}} 66 |
67 |68 | Email: {{$applicant->contact_email}} 69 |
70 |71 | Message: {{$applicant->message}} 72 |
73 |74 | 76 | Download Resume 77 | 78 |
79 | {{-- Delete Applicant --}} 80 | 88 |No applicants for this job
91 | @endforelse 92 |You have not job listings
95 | @endforelse 96 |There has been a new job application to your Workopia listing.
12 | 13 |Job Title: {{$job->title}}
14 | 15 |Application Details:
16 | 17 |Full Name: {{$application->full_name}}
18 |Contact Phone: {{$application->contact_phone}}
19 |Contact Email: {{$application->contact_email}}
20 |Message: {{$application->message}}
21 |Location: {{$application->location}}
22 | 23 |Login to your Workopia account to view the application.
24 | 25 | 26 | -------------------------------------------------------------------------------- /resources/views/jobs/bookmarked.blade.php: -------------------------------------------------------------------------------- 1 |You have no bookmarked jobs
10 | @endforelse 11 |No jobs available
19 | @endforelse 20 |32 | {{$job->description}} 33 |
34 |64 | {{$job->requirements}} 65 |
66 |70 | {{$job->benefits}} 71 |
72 |77 | Put "Job Application" as the subject of your email 78 | and attach your resume. 79 |
80 | 81 |111 | You must be logged in to apply for this job 112 |
113 | @endauth 114 |No jobs available
8 | @endforelse 9 |