├── .gitignore ├── README.md ├── _theme_files ├── add-job.html ├── css │ └── styles.css ├── images │ └── logo.png ├── index.html ├── job.html ├── jobs.html └── not-found.html ├── index.html ├── jsconfig.json ├── package-lock.json ├── package.json ├── postcss.config.js ├── public ├── favicon.ico └── screen.png ├── src ├── App.vue ├── App2.vue ├── assets │ ├── img │ │ └── logo.png │ └── main.css ├── components │ ├── BackButton.vue │ ├── Card.vue │ ├── Hero.vue │ ├── HomeCards.vue │ ├── JobListing.vue │ ├── JobListings.vue │ └── Navbar.vue ├── jobs copy.json ├── jobs.json ├── main.js ├── router │ └── index.js └── views │ ├── AddJobView.vue │ ├── EditJobView.vue │ ├── HomeView.vue │ ├── JobView.vue │ ├── JobsView.vue │ └── NotFoundView.vue ├── tailwind.config.js └── vite.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | .DS_Store 12 | dist 13 | dist-ssr 14 | coverage 15 | *.local 16 | .vscode 17 | 18 | /cypress/videos/ 19 | /cypress/screenshots/ 20 | 21 | # Editor directories and files 22 | .vscode/* 23 | !.vscode/extensions.json 24 | .idea 25 | *.suo 26 | *.ntvs* 27 | *.njsproj 28 | *.sln 29 | *.sw? 30 | 31 | *.tsbuildinfo 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Vue Jobs Project (YouTube) 2 | 3 | This is the jobs listing project from the [YouTube crash course](https://www.youtube.com/watch?v=VeNfHj6MhgA). 4 | 5 | 6 | 7 | ## Usage 8 | 9 | This project uses JSON-Server for a mock backend. 10 | 11 | ### Install Dependencies 12 | 13 | ```bash 14 | npm install 15 | ``` 16 | 17 | ### Run JSON Server 18 | 19 | The server will run on http://localhost:8000 20 | 21 | ```bash 22 | npm run server 23 | ``` 24 | 25 | ### Run Vite Frontend 26 | 27 | Vue will run on http://localhost:3000 28 | 29 | ```bash 30 | npm run dev 31 | ``` 32 | 33 | ### Build for Production 34 | 35 | ```bash 36 | npm run build 37 | ``` 38 | 39 | ### Preview Production Build 40 | 41 | ```bash 42 | npm run preview 43 | ``` 44 | -------------------------------------------------------------------------------- /_theme_files/add-job.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 13 | 14 | 15 | Vue Jobs | Become a Vue Developer 16 | 17 | 18 | 54 | 55 |
56 |
57 |
60 |
61 |

Add Job

62 | 63 |
64 | 67 | 78 |
79 | 80 |
81 | 84 | 92 |
93 |
94 | 99 | 106 |
107 | 108 |
109 | 112 | 130 |
131 | 132 |
133 | 136 | 144 |
145 | 146 |

Company Info

147 | 148 |
149 | 152 | 159 |
160 | 161 |
162 | 167 | 174 |
175 | 176 |
177 | 182 | 190 |
191 |
192 | 197 | 204 |
205 | 206 |
207 | 213 |
214 |
215 |
216 |
217 |
218 | 219 | 220 | 221 | 222 | -------------------------------------------------------------------------------- /_theme_files/css/styles.css: -------------------------------------------------------------------------------- 1 | /* 2 | ! tailwindcss v3.4.4 | MIT License | https://tailwindcss.com 3 | */ 4 | 5 | /* 6 | 1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) 7 | 2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) 8 | */ 9 | 10 | *, 11 | ::before, 12 | ::after { 13 | box-sizing: border-box; 14 | /* 1 */ 15 | border-width: 0; 16 | /* 2 */ 17 | border-style: solid; 18 | /* 2 */ 19 | border-color: #e5e7eb; 20 | /* 2 */ 21 | } 22 | 23 | ::before, 24 | ::after { 25 | --tw-content: ''; 26 | } 27 | 28 | /* 29 | 1. Use a consistent sensible line-height in all browsers. 30 | 2. Prevent adjustments of font size after orientation changes in iOS. 31 | 3. Use a more readable tab size. 32 | 4. Use the user's configured `sans` font-family by default. 33 | 5. Use the user's configured `sans` font-feature-settings by default. 34 | 6. Use the user's configured `sans` font-variation-settings by default. 35 | 7. Disable tap highlights on iOS 36 | */ 37 | 38 | html, 39 | :host { 40 | line-height: 1.5; 41 | /* 1 */ 42 | -webkit-text-size-adjust: 100%; 43 | /* 2 */ 44 | -moz-tab-size: 4; 45 | /* 3 */ 46 | -o-tab-size: 4; 47 | tab-size: 4; 48 | /* 3 */ 49 | font-family: Poppins, sans-serif; 50 | /* 4 */ 51 | font-feature-settings: normal; 52 | /* 5 */ 53 | font-variation-settings: normal; 54 | /* 6 */ 55 | -webkit-tap-highlight-color: transparent; 56 | /* 7 */ 57 | } 58 | 59 | /* 60 | 1. Remove the margin in all browsers. 61 | 2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. 62 | */ 63 | 64 | body { 65 | margin: 0; 66 | /* 1 */ 67 | line-height: inherit; 68 | /* 2 */ 69 | } 70 | 71 | /* 72 | 1. Add the correct height in Firefox. 73 | 2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) 74 | 3. Ensure horizontal rules are visible by default. 75 | */ 76 | 77 | hr { 78 | height: 0; 79 | /* 1 */ 80 | color: inherit; 81 | /* 2 */ 82 | border-top-width: 1px; 83 | /* 3 */ 84 | } 85 | 86 | /* 87 | Add the correct text decoration in Chrome, Edge, and Safari. 88 | */ 89 | 90 | abbr:where([title]) { 91 | -webkit-text-decoration: underline dotted; 92 | text-decoration: underline dotted; 93 | } 94 | 95 | /* 96 | Remove the default font size and weight for headings. 97 | */ 98 | 99 | h1, 100 | h2, 101 | h3, 102 | h4, 103 | h5, 104 | h6 { 105 | font-size: inherit; 106 | font-weight: inherit; 107 | } 108 | 109 | /* 110 | Reset links to optimize for opt-in styling instead of opt-out. 111 | */ 112 | 113 | a { 114 | color: inherit; 115 | text-decoration: inherit; 116 | } 117 | 118 | /* 119 | Add the correct font weight in Edge and Safari. 120 | */ 121 | 122 | b, 123 | strong { 124 | font-weight: bolder; 125 | } 126 | 127 | /* 128 | 1. Use the user's configured `mono` font-family by default. 129 | 2. Use the user's configured `mono` font-feature-settings by default. 130 | 3. Use the user's configured `mono` font-variation-settings by default. 131 | 4. Correct the odd `em` font sizing in all browsers. 132 | */ 133 | 134 | code, 135 | kbd, 136 | samp, 137 | pre { 138 | font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; 139 | /* 1 */ 140 | font-feature-settings: normal; 141 | /* 2 */ 142 | font-variation-settings: normal; 143 | /* 3 */ 144 | font-size: 1em; 145 | /* 4 */ 146 | } 147 | 148 | /* 149 | Add the correct font size in all browsers. 150 | */ 151 | 152 | small { 153 | font-size: 80%; 154 | } 155 | 156 | /* 157 | Prevent `sub` and `sup` elements from affecting the line height in all browsers. 158 | */ 159 | 160 | sub, 161 | sup { 162 | font-size: 75%; 163 | line-height: 0; 164 | position: relative; 165 | vertical-align: baseline; 166 | } 167 | 168 | sub { 169 | bottom: -0.25em; 170 | } 171 | 172 | sup { 173 | top: -0.5em; 174 | } 175 | 176 | /* 177 | 1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) 178 | 2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) 179 | 3. Remove gaps between table borders by default. 180 | */ 181 | 182 | table { 183 | text-indent: 0; 184 | /* 1 */ 185 | border-color: inherit; 186 | /* 2 */ 187 | border-collapse: collapse; 188 | /* 3 */ 189 | } 190 | 191 | /* 192 | 1. Change the font styles in all browsers. 193 | 2. Remove the margin in Firefox and Safari. 194 | 3. Remove default padding in all browsers. 195 | */ 196 | 197 | button, 198 | input, 199 | optgroup, 200 | select, 201 | textarea { 202 | font-family: inherit; 203 | /* 1 */ 204 | font-feature-settings: inherit; 205 | /* 1 */ 206 | font-variation-settings: inherit; 207 | /* 1 */ 208 | font-size: 100%; 209 | /* 1 */ 210 | font-weight: inherit; 211 | /* 1 */ 212 | line-height: inherit; 213 | /* 1 */ 214 | letter-spacing: inherit; 215 | /* 1 */ 216 | color: inherit; 217 | /* 1 */ 218 | margin: 0; 219 | /* 2 */ 220 | padding: 0; 221 | /* 3 */ 222 | } 223 | 224 | /* 225 | Remove the inheritance of text transform in Edge and Firefox. 226 | */ 227 | 228 | button, 229 | select { 230 | text-transform: none; 231 | } 232 | 233 | /* 234 | 1. Correct the inability to style clickable types in iOS and Safari. 235 | 2. Remove default button styles. 236 | */ 237 | 238 | button, 239 | input:where([type='button']), 240 | input:where([type='reset']), 241 | input:where([type='submit']) { 242 | -webkit-appearance: button; 243 | /* 1 */ 244 | background-color: transparent; 245 | /* 2 */ 246 | background-image: none; 247 | /* 2 */ 248 | } 249 | 250 | /* 251 | Use the modern Firefox focus style for all focusable elements. 252 | */ 253 | 254 | :-moz-focusring { 255 | outline: auto; 256 | } 257 | 258 | /* 259 | Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) 260 | */ 261 | 262 | :-moz-ui-invalid { 263 | box-shadow: none; 264 | } 265 | 266 | /* 267 | Add the correct vertical alignment in Chrome and Firefox. 268 | */ 269 | 270 | progress { 271 | vertical-align: baseline; 272 | } 273 | 274 | /* 275 | Correct the cursor style of increment and decrement buttons in Safari. 276 | */ 277 | 278 | ::-webkit-inner-spin-button, 279 | ::-webkit-outer-spin-button { 280 | height: auto; 281 | } 282 | 283 | /* 284 | 1. Correct the odd appearance in Chrome and Safari. 285 | 2. Correct the outline style in Safari. 286 | */ 287 | 288 | [type='search'] { 289 | -webkit-appearance: textfield; 290 | /* 1 */ 291 | outline-offset: -2px; 292 | /* 2 */ 293 | } 294 | 295 | /* 296 | Remove the inner padding in Chrome and Safari on macOS. 297 | */ 298 | 299 | ::-webkit-search-decoration { 300 | -webkit-appearance: none; 301 | } 302 | 303 | /* 304 | 1. Correct the inability to style clickable types in iOS and Safari. 305 | 2. Change font properties to `inherit` in Safari. 306 | */ 307 | 308 | ::-webkit-file-upload-button { 309 | -webkit-appearance: button; 310 | /* 1 */ 311 | font: inherit; 312 | /* 2 */ 313 | } 314 | 315 | /* 316 | Add the correct display in Chrome and Safari. 317 | */ 318 | 319 | summary { 320 | display: list-item; 321 | } 322 | 323 | /* 324 | Removes the default spacing and border for appropriate elements. 325 | */ 326 | 327 | blockquote, 328 | dl, 329 | dd, 330 | h1, 331 | h2, 332 | h3, 333 | h4, 334 | h5, 335 | h6, 336 | hr, 337 | figure, 338 | p, 339 | pre { 340 | margin: 0; 341 | } 342 | 343 | fieldset { 344 | margin: 0; 345 | padding: 0; 346 | } 347 | 348 | legend { 349 | padding: 0; 350 | } 351 | 352 | ol, 353 | ul, 354 | menu { 355 | list-style: none; 356 | margin: 0; 357 | padding: 0; 358 | } 359 | 360 | /* 361 | Reset default styling for dialogs. 362 | */ 363 | 364 | dialog { 365 | padding: 0; 366 | } 367 | 368 | /* 369 | Prevent resizing textareas horizontally by default. 370 | */ 371 | 372 | textarea { 373 | resize: vertical; 374 | } 375 | 376 | /* 377 | 1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) 378 | 2. Set the default placeholder color to the user's configured gray 400 color. 379 | */ 380 | 381 | input::-moz-placeholder, textarea::-moz-placeholder { 382 | opacity: 1; 383 | /* 1 */ 384 | color: #9ca3af; 385 | /* 2 */ 386 | } 387 | 388 | input::placeholder, 389 | textarea::placeholder { 390 | opacity: 1; 391 | /* 1 */ 392 | color: #9ca3af; 393 | /* 2 */ 394 | } 395 | 396 | /* 397 | Set the default cursor for buttons. 398 | */ 399 | 400 | button, 401 | [role="button"] { 402 | cursor: pointer; 403 | } 404 | 405 | /* 406 | Make sure disabled buttons don't get the pointer cursor. 407 | */ 408 | 409 | :disabled { 410 | cursor: default; 411 | } 412 | 413 | /* 414 | 1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) 415 | 2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) 416 | This can trigger a poorly considered lint error in some tools but is included by design. 417 | */ 418 | 419 | img, 420 | svg, 421 | video, 422 | canvas, 423 | audio, 424 | iframe, 425 | embed, 426 | object { 427 | display: block; 428 | /* 1 */ 429 | vertical-align: middle; 430 | /* 2 */ 431 | } 432 | 433 | /* 434 | Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) 435 | */ 436 | 437 | img, 438 | video { 439 | max-width: 100%; 440 | height: auto; 441 | } 442 | 443 | /* Make elements with the HTML hidden attribute stay hidden by default */ 444 | 445 | [hidden] { 446 | display: none; 447 | } 448 | 449 | *, ::before, ::after { 450 | --tw-border-spacing-x: 0; 451 | --tw-border-spacing-y: 0; 452 | --tw-translate-x: 0; 453 | --tw-translate-y: 0; 454 | --tw-rotate: 0; 455 | --tw-skew-x: 0; 456 | --tw-skew-y: 0; 457 | --tw-scale-x: 1; 458 | --tw-scale-y: 1; 459 | --tw-pan-x: ; 460 | --tw-pan-y: ; 461 | --tw-pinch-zoom: ; 462 | --tw-scroll-snap-strictness: proximity; 463 | --tw-gradient-from-position: ; 464 | --tw-gradient-via-position: ; 465 | --tw-gradient-to-position: ; 466 | --tw-ordinal: ; 467 | --tw-slashed-zero: ; 468 | --tw-numeric-figure: ; 469 | --tw-numeric-spacing: ; 470 | --tw-numeric-fraction: ; 471 | --tw-ring-inset: ; 472 | --tw-ring-offset-width: 0px; 473 | --tw-ring-offset-color: #fff; 474 | --tw-ring-color: rgb(59 130 246 / 0.5); 475 | --tw-ring-offset-shadow: 0 0 #0000; 476 | --tw-ring-shadow: 0 0 #0000; 477 | --tw-shadow: 0 0 #0000; 478 | --tw-shadow-colored: 0 0 #0000; 479 | --tw-blur: ; 480 | --tw-brightness: ; 481 | --tw-contrast: ; 482 | --tw-grayscale: ; 483 | --tw-hue-rotate: ; 484 | --tw-invert: ; 485 | --tw-saturate: ; 486 | --tw-sepia: ; 487 | --tw-drop-shadow: ; 488 | --tw-backdrop-blur: ; 489 | --tw-backdrop-brightness: ; 490 | --tw-backdrop-contrast: ; 491 | --tw-backdrop-grayscale: ; 492 | --tw-backdrop-hue-rotate: ; 493 | --tw-backdrop-invert: ; 494 | --tw-backdrop-opacity: ; 495 | --tw-backdrop-saturate: ; 496 | --tw-backdrop-sepia: ; 497 | --tw-contain-size: ; 498 | --tw-contain-layout: ; 499 | --tw-contain-paint: ; 500 | --tw-contain-style: ; 501 | } 502 | 503 | ::backdrop { 504 | --tw-border-spacing-x: 0; 505 | --tw-border-spacing-y: 0; 506 | --tw-translate-x: 0; 507 | --tw-translate-y: 0; 508 | --tw-rotate: 0; 509 | --tw-skew-x: 0; 510 | --tw-skew-y: 0; 511 | --tw-scale-x: 1; 512 | --tw-scale-y: 1; 513 | --tw-pan-x: ; 514 | --tw-pan-y: ; 515 | --tw-pinch-zoom: ; 516 | --tw-scroll-snap-strictness: proximity; 517 | --tw-gradient-from-position: ; 518 | --tw-gradient-via-position: ; 519 | --tw-gradient-to-position: ; 520 | --tw-ordinal: ; 521 | --tw-slashed-zero: ; 522 | --tw-numeric-figure: ; 523 | --tw-numeric-spacing: ; 524 | --tw-numeric-fraction: ; 525 | --tw-ring-inset: ; 526 | --tw-ring-offset-width: 0px; 527 | --tw-ring-offset-color: #fff; 528 | --tw-ring-color: rgb(59 130 246 / 0.5); 529 | --tw-ring-offset-shadow: 0 0 #0000; 530 | --tw-ring-shadow: 0 0 #0000; 531 | --tw-shadow: 0 0 #0000; 532 | --tw-shadow-colored: 0 0 #0000; 533 | --tw-blur: ; 534 | --tw-brightness: ; 535 | --tw-contrast: ; 536 | --tw-grayscale: ; 537 | --tw-hue-rotate: ; 538 | --tw-invert: ; 539 | --tw-saturate: ; 540 | --tw-sepia: ; 541 | --tw-drop-shadow: ; 542 | --tw-backdrop-blur: ; 543 | --tw-backdrop-brightness: ; 544 | --tw-backdrop-contrast: ; 545 | --tw-backdrop-grayscale: ; 546 | --tw-backdrop-hue-rotate: ; 547 | --tw-backdrop-invert: ; 548 | --tw-backdrop-opacity: ; 549 | --tw-backdrop-saturate: ; 550 | --tw-backdrop-sepia: ; 551 | --tw-contain-size: ; 552 | --tw-contain-layout: ; 553 | --tw-contain-paint: ; 554 | --tw-contain-style: ; 555 | } 556 | 557 | .container { 558 | width: 100%; 559 | } 560 | 561 | @media (min-width: 640px) { 562 | .container { 563 | max-width: 640px; 564 | } 565 | } 566 | 567 | @media (min-width: 768px) { 568 | .container { 569 | max-width: 768px; 570 | } 571 | } 572 | 573 | @media (min-width: 1024px) { 574 | .container { 575 | max-width: 1024px; 576 | } 577 | } 578 | 579 | @media (min-width: 1280px) { 580 | .container { 581 | max-width: 1280px; 582 | } 583 | } 584 | 585 | @media (min-width: 1536px) { 586 | .container { 587 | max-width: 1536px; 588 | } 589 | } 590 | 591 | .relative { 592 | position: relative; 593 | } 594 | 595 | .m-4 { 596 | margin: 1rem; 597 | } 598 | 599 | .m-auto { 600 | margin: auto; 601 | } 602 | 603 | .mx-auto { 604 | margin-left: auto; 605 | margin-right: auto; 606 | } 607 | 608 | .my-10 { 609 | margin-top: 2.5rem; 610 | margin-bottom: 2.5rem; 611 | } 612 | 613 | .my-2 { 614 | margin-top: 0.5rem; 615 | margin-bottom: 0.5rem; 616 | } 617 | 618 | .my-4 { 619 | margin-top: 1rem; 620 | margin-bottom: 1rem; 621 | } 622 | 623 | .mb-2 { 624 | margin-bottom: 0.5rem; 625 | } 626 | 627 | .mb-3 { 628 | margin-bottom: 0.75rem; 629 | } 630 | 631 | .mb-4 { 632 | margin-bottom: 1rem; 633 | } 634 | 635 | .mb-5 { 636 | margin-bottom: 1.25rem; 637 | } 638 | 639 | .mb-6 { 640 | margin-bottom: 1.5rem; 641 | } 642 | 643 | .ml-2 { 644 | margin-left: 0.5rem; 645 | } 646 | 647 | .mr-2 { 648 | margin-right: 0.5rem; 649 | } 650 | 651 | .mr-4 { 652 | margin-right: 1rem; 653 | } 654 | 655 | .mt-2 { 656 | margin-top: 0.5rem; 657 | } 658 | 659 | .mt-4 { 660 | margin-top: 1rem; 661 | } 662 | 663 | .mt-6 { 664 | margin-top: 1.5rem; 665 | } 666 | 667 | .block { 668 | display: block; 669 | } 670 | 671 | .inline-block { 672 | display: inline-block; 673 | } 674 | 675 | .flex { 676 | display: flex; 677 | } 678 | 679 | .grid { 680 | display: grid; 681 | } 682 | 683 | .hidden { 684 | display: none; 685 | } 686 | 687 | .h-10 { 688 | height: 2.5rem; 689 | } 690 | 691 | .h-20 { 692 | height: 5rem; 693 | } 694 | 695 | .h-96 { 696 | height: 24rem; 697 | } 698 | 699 | .h-\[36px\] { 700 | height: 36px; 701 | } 702 | 703 | .w-auto { 704 | width: auto; 705 | } 706 | 707 | .w-full { 708 | width: 100%; 709 | } 710 | 711 | .max-w-2xl { 712 | max-width: 42rem; 713 | } 714 | 715 | .max-w-7xl { 716 | max-width: 80rem; 717 | } 718 | 719 | .max-w-lg { 720 | max-width: 32rem; 721 | } 722 | 723 | .flex-1 { 724 | flex: 1 1 0%; 725 | } 726 | 727 | .flex-shrink-0 { 728 | flex-shrink: 0; 729 | } 730 | 731 | .grid-cols-1 { 732 | grid-template-columns: repeat(1, minmax(0, 1fr)); 733 | } 734 | 735 | .flex-col { 736 | flex-direction: column; 737 | } 738 | 739 | .items-center { 740 | align-items: center; 741 | } 742 | 743 | .justify-center { 744 | justify-content: center; 745 | } 746 | 747 | .justify-between { 748 | justify-content: space-between; 749 | } 750 | 751 | .gap-4 { 752 | gap: 1rem; 753 | } 754 | 755 | .gap-6 { 756 | gap: 1.5rem; 757 | } 758 | 759 | .space-x-2 > :not([hidden]) ~ :not([hidden]) { 760 | --tw-space-x-reverse: 0; 761 | margin-right: calc(0.5rem * var(--tw-space-x-reverse)); 762 | margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse))); 763 | } 764 | 765 | .rounded { 766 | border-radius: 0.25rem; 767 | } 768 | 769 | .rounded-full { 770 | border-radius: 9999px; 771 | } 772 | 773 | .rounded-lg { 774 | border-radius: 0.5rem; 775 | } 776 | 777 | .rounded-md { 778 | border-radius: 0.375rem; 779 | } 780 | 781 | .rounded-xl { 782 | border-radius: 0.75rem; 783 | } 784 | 785 | .border { 786 | border-width: 1px; 787 | } 788 | 789 | .border-b { 790 | border-bottom-width: 1px; 791 | } 792 | 793 | .border-gray-100 { 794 | --tw-border-opacity: 1; 795 | border-color: rgb(243 244 246 / var(--tw-border-opacity)); 796 | } 797 | 798 | .border-gray-300 { 799 | --tw-border-opacity: 1; 800 | border-color: rgb(209 213 219 / var(--tw-border-opacity)); 801 | } 802 | 803 | .border-green-500 { 804 | --tw-border-opacity: 1; 805 | border-color: rgb(34 197 94 / var(--tw-border-opacity)); 806 | } 807 | 808 | .bg-black { 809 | --tw-bg-opacity: 1; 810 | background-color: rgb(0 0 0 / var(--tw-bg-opacity)); 811 | } 812 | 813 | .bg-blue-50 { 814 | --tw-bg-opacity: 1; 815 | background-color: rgb(239 246 255 / var(--tw-bg-opacity)); 816 | } 817 | 818 | .bg-gray-100 { 819 | --tw-bg-opacity: 1; 820 | background-color: rgb(243 244 246 / var(--tw-bg-opacity)); 821 | } 822 | 823 | .bg-green-100 { 824 | --tw-bg-opacity: 1; 825 | background-color: rgb(220 252 231 / var(--tw-bg-opacity)); 826 | } 827 | 828 | .bg-green-50 { 829 | --tw-bg-opacity: 1; 830 | background-color: rgb(240 253 244 / var(--tw-bg-opacity)); 831 | } 832 | 833 | .bg-green-500 { 834 | --tw-bg-opacity: 1; 835 | background-color: rgb(34 197 94 / var(--tw-bg-opacity)); 836 | } 837 | 838 | .bg-green-700 { 839 | --tw-bg-opacity: 1; 840 | background-color: rgb(21 128 61 / var(--tw-bg-opacity)); 841 | } 842 | 843 | .bg-green-900 { 844 | --tw-bg-opacity: 1; 845 | background-color: rgb(20 83 45 / var(--tw-bg-opacity)); 846 | } 847 | 848 | .bg-red-500 { 849 | --tw-bg-opacity: 1; 850 | background-color: rgb(239 68 68 / var(--tw-bg-opacity)); 851 | } 852 | 853 | .bg-white { 854 | --tw-bg-opacity: 1; 855 | background-color: rgb(255 255 255 / var(--tw-bg-opacity)); 856 | } 857 | 858 | .p-2 { 859 | padding: 0.5rem; 860 | } 861 | 862 | .p-3 { 863 | padding: 0.75rem; 864 | } 865 | 866 | .p-4 { 867 | padding: 1rem; 868 | } 869 | 870 | .p-6 { 871 | padding: 1.5rem; 872 | } 873 | 874 | .px-2 { 875 | padding-left: 0.5rem; 876 | padding-right: 0.5rem; 877 | } 878 | 879 | .px-3 { 880 | padding-left: 0.75rem; 881 | padding-right: 0.75rem; 882 | } 883 | 884 | .px-4 { 885 | padding-left: 1rem; 886 | padding-right: 1rem; 887 | } 888 | 889 | .px-6 { 890 | padding-left: 1.5rem; 891 | padding-right: 1.5rem; 892 | } 893 | 894 | .py-10 { 895 | padding-top: 2.5rem; 896 | padding-bottom: 2.5rem; 897 | } 898 | 899 | .py-2 { 900 | padding-top: 0.5rem; 901 | padding-bottom: 0.5rem; 902 | } 903 | 904 | .py-20 { 905 | padding-top: 5rem; 906 | padding-bottom: 5rem; 907 | } 908 | 909 | .py-24 { 910 | padding-top: 6rem; 911 | padding-bottom: 6rem; 912 | } 913 | 914 | .py-4 { 915 | padding-top: 1rem; 916 | padding-bottom: 1rem; 917 | } 918 | 919 | .py-6 { 920 | padding-top: 1.5rem; 921 | padding-bottom: 1.5rem; 922 | } 923 | 924 | .py-8 { 925 | padding-top: 2rem; 926 | padding-bottom: 2rem; 927 | } 928 | 929 | .text-center { 930 | text-align: center; 931 | } 932 | 933 | .align-middle { 934 | vertical-align: middle; 935 | } 936 | 937 | .text-2xl { 938 | font-size: 1.5rem; 939 | line-height: 2rem; 940 | } 941 | 942 | .text-3xl { 943 | font-size: 1.875rem; 944 | line-height: 2.25rem; 945 | } 946 | 947 | .text-4xl { 948 | font-size: 2.25rem; 949 | line-height: 2.5rem; 950 | } 951 | 952 | .text-6xl { 953 | font-size: 3.75rem; 954 | line-height: 1; 955 | } 956 | 957 | .text-lg { 958 | font-size: 1.125rem; 959 | line-height: 1.75rem; 960 | } 961 | 962 | .text-sm { 963 | font-size: 0.875rem; 964 | line-height: 1.25rem; 965 | } 966 | 967 | .text-xl { 968 | font-size: 1.25rem; 969 | line-height: 1.75rem; 970 | } 971 | 972 | .font-bold { 973 | font-weight: 700; 974 | } 975 | 976 | .font-extrabold { 977 | font-weight: 800; 978 | } 979 | 980 | .font-semibold { 981 | font-weight: 600; 982 | } 983 | 984 | .text-gray-500 { 985 | --tw-text-opacity: 1; 986 | color: rgb(107 114 128 / var(--tw-text-opacity)); 987 | } 988 | 989 | .text-gray-600 { 990 | --tw-text-opacity: 1; 991 | color: rgb(75 85 99 / var(--tw-text-opacity)); 992 | } 993 | 994 | .text-gray-700 { 995 | --tw-text-opacity: 1; 996 | color: rgb(55 65 81 / var(--tw-text-opacity)); 997 | } 998 | 999 | .text-green-500 { 1000 | --tw-text-opacity: 1; 1001 | color: rgb(34 197 94 / var(--tw-text-opacity)); 1002 | } 1003 | 1004 | .text-green-800 { 1005 | --tw-text-opacity: 1; 1006 | color: rgb(22 101 52 / var(--tw-text-opacity)); 1007 | } 1008 | 1009 | .text-orange-700 { 1010 | --tw-text-opacity: 1; 1011 | color: rgb(194 65 12 / var(--tw-text-opacity)); 1012 | } 1013 | 1014 | .text-white { 1015 | --tw-text-opacity: 1; 1016 | color: rgb(255 255 255 / var(--tw-text-opacity)); 1017 | } 1018 | 1019 | .text-yellow-400 { 1020 | --tw-text-opacity: 1; 1021 | color: rgb(250 204 21 / var(--tw-text-opacity)); 1022 | } 1023 | 1024 | .shadow-md { 1025 | --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); 1026 | --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color); 1027 | box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); 1028 | } 1029 | 1030 | @media (min-width: 1024px) { 1031 | .lg\:container { 1032 | width: 100%; 1033 | } 1034 | 1035 | @media (min-width: 640px) { 1036 | .lg\:container { 1037 | max-width: 640px; 1038 | } 1039 | } 1040 | 1041 | @media (min-width: 768px) { 1042 | .lg\:container { 1043 | max-width: 768px; 1044 | } 1045 | } 1046 | 1047 | @media (min-width: 1024px) { 1048 | .lg\:container { 1049 | max-width: 1024px; 1050 | } 1051 | } 1052 | 1053 | @media (min-width: 1280px) { 1054 | .lg\:container { 1055 | max-width: 1280px; 1056 | } 1057 | } 1058 | 1059 | @media (min-width: 1536px) { 1060 | .lg\:container { 1061 | max-width: 1536px; 1062 | } 1063 | } 1064 | } 1065 | 1066 | .hover\:bg-gray-700:hover { 1067 | --tw-bg-opacity: 1; 1068 | background-color: rgb(55 65 81 / var(--tw-bg-opacity)); 1069 | } 1070 | 1071 | .hover\:bg-gray-900:hover { 1072 | --tw-bg-opacity: 1; 1073 | background-color: rgb(17 24 39 / var(--tw-bg-opacity)); 1074 | } 1075 | 1076 | .hover\:bg-green-600:hover { 1077 | --tw-bg-opacity: 1; 1078 | background-color: rgb(22 163 74 / var(--tw-bg-opacity)); 1079 | } 1080 | 1081 | .hover\:bg-green-900:hover { 1082 | --tw-bg-opacity: 1; 1083 | background-color: rgb(20 83 45 / var(--tw-bg-opacity)); 1084 | } 1085 | 1086 | .hover\:bg-red-600:hover { 1087 | --tw-bg-opacity: 1; 1088 | background-color: rgb(220 38 38 / var(--tw-bg-opacity)); 1089 | } 1090 | 1091 | .hover\:text-green-600:hover { 1092 | --tw-text-opacity: 1; 1093 | color: rgb(22 163 74 / var(--tw-text-opacity)); 1094 | } 1095 | 1096 | .hover\:text-white:hover { 1097 | --tw-text-opacity: 1; 1098 | color: rgb(255 255 255 / var(--tw-text-opacity)); 1099 | } 1100 | 1101 | .focus\:border-green-500:focus { 1102 | --tw-border-opacity: 1; 1103 | border-color: rgb(34 197 94 / var(--tw-border-opacity)); 1104 | } 1105 | 1106 | .focus\:outline-none:focus { 1107 | outline: 2px solid transparent; 1108 | outline-offset: 2px; 1109 | } 1110 | 1111 | @media (min-width: 640px) { 1112 | .sm\:px-6 { 1113 | padding-left: 1.5rem; 1114 | padding-right: 1.5rem; 1115 | } 1116 | 1117 | .sm\:text-5xl { 1118 | font-size: 3rem; 1119 | line-height: 1; 1120 | } 1121 | } 1122 | 1123 | @media (min-width: 768px) { 1124 | .md\:m-0 { 1125 | margin: 0px; 1126 | } 1127 | 1128 | .md\:ml-auto { 1129 | margin-left: auto; 1130 | } 1131 | 1132 | .md\:block { 1133 | display: block; 1134 | } 1135 | 1136 | .md\:grid-cols-2 { 1137 | grid-template-columns: repeat(2, minmax(0, 1fr)); 1138 | } 1139 | 1140 | .md\:grid-cols-3 { 1141 | grid-template-columns: repeat(3, minmax(0, 1fr)); 1142 | } 1143 | 1144 | .md\:grid-cols-70\/30 { 1145 | grid-template-columns: 70% 28%; 1146 | } 1147 | 1148 | .md\:items-stretch { 1149 | align-items: stretch; 1150 | } 1151 | 1152 | .md\:justify-start { 1153 | justify-content: flex-start; 1154 | } 1155 | 1156 | .md\:text-left { 1157 | text-align: left; 1158 | } 1159 | 1160 | .md\:text-6xl { 1161 | font-size: 3.75rem; 1162 | line-height: 1; 1163 | } 1164 | } 1165 | 1166 | @media (min-width: 1024px) { 1167 | .lg\:flex-row { 1168 | flex-direction: row; 1169 | } 1170 | 1171 | .lg\:px-8 { 1172 | padding-left: 2rem; 1173 | padding-right: 2rem; 1174 | } 1175 | } 1176 | -------------------------------------------------------------------------------- /_theme_files/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/vue-crash-2024/d495fb10d91c10bf79cff0c665773ddad8e0fa65/_theme_files/images/logo.png -------------------------------------------------------------------------------- /_theme_files/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 13 | 14 | 15 | Vue Jobs | Become a Vue Developer 16 | 17 | 18 | 54 | 55 | 56 |
57 |
60 |
61 |

64 | Become a Vue Dev 65 |

66 |

67 | Find the Vue job that fits your skills and needs 68 |

69 |
70 |
71 |
72 | 73 | 74 |
75 |
76 |
77 |
78 |

For Developers

79 |

80 | Browse our Vue jobs and start your career today 81 |

82 | 86 | Browse Jobs 87 | 88 |
89 |
90 |

For Employers

91 |

92 | List your job to find the perfect developer for the role 93 |

94 | 98 | Add Job 99 | 100 |
101 |
102 |
103 |
104 | 105 | 106 |
107 |
108 |

109 | Browse Jobs 110 |

111 |
112 | 113 |
114 |
115 |
116 |
Full-Time
117 |

Senior Vue Developer

118 |
119 | 120 |
121 | We are seeking a talented Front-End Developer to join our team 122 | in Boston, MA. The ideal candidate will have strong skills in 123 | HTML, CSS, and JavaScript... 124 |
125 | 126 |

$70 - $80K / Year

127 | 128 |
129 | 130 |
131 |
132 | 133 | Boston, MA 134 |
135 | 139 | Read More 140 | 141 |
142 |
143 |
144 | 145 |
146 |
147 |
148 |
Remote
149 |

Front-End Engineer (Vue)

150 |
151 | 152 |
153 | Join our team as a Front-End Developer in sunny Miami, FL. We 154 | are looking for a motivated individual with a passion... 155 |
156 | 157 |

$70K - $80K / Year

158 | 159 |
160 | 161 |
162 |
163 | 164 | Miami, FL 165 |
166 | 170 | Read More 171 | 172 |
173 |
174 |
175 | 176 |
177 |
178 |
179 |
Remote
180 |

Vue.js Developer

181 |
182 | 183 |
184 | Are you passionate about front-end development? Join our team in 185 | vibrant Brooklyn, NY, and work on exciting projects that make a 186 | difference... 187 |
188 | 189 |

$70K - $80K / Year

190 | 191 |
192 | 193 |
194 |
195 | 196 | Brooklyn, NY 197 |
198 | 202 | Read More 203 | 204 |
205 |
206 |
207 |
208 |
209 |
210 | 211 |
212 | View All Jobs 217 |
218 | 219 | 220 | 221 | 222 | -------------------------------------------------------------------------------- /_theme_files/job.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 13 | 14 | 15 | Vue Jobs | Become a Vue Developer 16 | 17 | 18 | 54 | 55 | 56 |
57 |
58 | 62 | Back to Job Listings 63 | 64 |
65 |
66 | 67 |
68 |
69 |
70 |
71 |
74 |
Full-Time
75 |

Senior Vue Developer

76 |
79 | 82 |

Boston, MA

83 |
84 |
85 | 86 |
87 |

88 | Job Description 89 |

90 | 91 |

92 | We are seeking a talented Front-End Developer to join our team 93 | in Boston, MA. The ideal candidate will have strong skills in 94 | HTML, CSS, and JavaScript, with experience working with modern 95 | JavaScript frameworks such as Vue or Angular. 96 |

97 | 98 |

Salary

99 | 100 |

$70k - $80K / Year

101 |
102 |
103 | 104 | 105 | 147 |
148 |
149 |
150 | 151 | 152 | 153 | 154 | -------------------------------------------------------------------------------- /_theme_files/jobs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 13 | 14 | 15 | Vue Jobs | Become a Vue Developer 16 | 17 | 18 | 54 | 55 | 56 |
57 |
58 |
59 | 64 |
65 |
66 |
67 | 68 | 69 |
70 |
71 |

72 | Browse Jobs 73 |

74 |
75 | 76 |
77 |
78 |
79 |
Full-Time
80 |

Senior Vue Developer

81 |
82 | 83 |
84 | We are seeking a talented Front-End Developer to join our team 85 | in Boston, MA. The ideal candidate will have strong skills in 86 | HTML, CSS, and JavaScript... 87 |
88 | 89 |

$70 - $80K / Year

90 | 91 |
92 | 93 |
94 |
95 | 96 | Boston, MA 97 |
98 | 102 | Read More 103 | 104 |
105 |
106 |
107 | 108 |
109 |
110 |
111 |
Remote
112 |

Front-End Engineer (Vue)

113 |
114 | 115 |
116 | Join our team as a Front-End Developer in sunny Miami, FL. We 117 | are looking for a motivated individual with a passion... 118 |
119 | 120 |

$70K - $80K / Year

121 | 122 |
123 | 124 |
125 |
126 | 127 | Miami, FL 128 |
129 | 133 | Read More 134 | 135 |
136 |
137 |
138 | 139 |
140 |
141 |
142 |
Remote
143 |

Vue.js Developer

144 |
145 | 146 |
147 | Are you passionate about front-end development? Join our team in 148 | vibrant Brooklyn, NY, and work on exciting projects that make a 149 | difference... 150 |
151 | 152 |

$70K - $80K / Year

153 | 154 |
155 | 156 |
157 |
158 | 159 | Brooklyn, NY 160 |
161 | 165 | Read More 166 | 167 |
168 |
169 |
170 | 171 | 172 |
173 |
174 |
175 |
Part-Time
176 |

Vue Front-End Developer

177 |
178 | 179 |
180 | Join our team as a Part-Time Front-End Developer in beautiful 181 | Pheonix, AZ. We are looking for a self-motivated individual with 182 | a passion... 183 |
184 | 185 |

$60 - $70K / Year

186 | 187 |
188 | 189 |
190 |
191 | 192 | Pheonix, AZ 193 |
194 | 198 | Read More 199 | 200 |
201 |
202 |
203 | 204 |
205 |
206 |
207 |
Full-Time
208 |

Full Stack Vue Developer

209 |
210 | 211 |
212 | Exciting opportunity for a Full-Time Front-End Developer in 213 | bustling Atlanta, GA. We are seeking a talented individual... 214 |
215 | 216 |

$90K - $100K / Year

217 | 218 |
219 | 220 |
221 |
222 | 223 | Miami, FL 224 |
225 | 229 | Read More 230 | 231 |
232 |
233 |
234 | 235 |
236 |
237 |
238 |
Remote
239 |

Vue Native Developer

240 |
241 | 242 |
243 | Join our team as a Front-End Developer in beautiful Portland, 244 | OR. We are looking for a skilled and enthusiastic individual... 245 |
246 | 247 |

$100K - $110K / Year

248 | 249 |
250 | 251 |
252 |
253 | 254 | Brooklyn, NY 255 |
256 | 260 | Read More 261 | 262 |
263 |
264 |
265 |
266 |
267 |
268 | 269 | 270 | 271 | 272 | -------------------------------------------------------------------------------- /_theme_files/not-found.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 13 | 14 | 15 | Vue Jobs | Become a Vue Developer 16 | 17 | 18 | 54 | 55 |
56 | 57 |

404 Not Found

58 |

This page does not exist

59 | Go Back 64 |
65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vue Jobs 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "paths": { 4 | "@/*": ["./src/*"] 5 | } 6 | }, 7 | "exclude": ["node_modules", "dist"] 8 | } 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-crash-2024", 3 | "version": "0.0.0", 4 | "private": true, 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "preview": "vite preview", 10 | "server": "json-server --watch src/jobs.json --port 8000" 11 | }, 12 | "dependencies": { 13 | "axios": "^1.7.2", 14 | "json-server": "^1.0.0-beta.1", 15 | "primeicons": "^7.0.0", 16 | "vue": "^3.4.29", 17 | "vue-router": "^4.4.0", 18 | "vue-spinner": "^1.0.4", 19 | "vue-toastification": "^2.0.0-rc.5" 20 | }, 21 | "devDependencies": { 22 | "@vitejs/plugin-vue": "^5.0.5", 23 | "autoprefixer": "^10.4.19", 24 | "postcss": "^8.4.38", 25 | "tailwindcss": "^3.4.4", 26 | "vite": "^5.3.1" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/vue-crash-2024/d495fb10d91c10bf79cff0c665773ddad8e0fa65/public/favicon.ico -------------------------------------------------------------------------------- /public/screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/vue-crash-2024/d495fb10d91c10bf79cff0c665773ddad8e0fa65/public/screen.png -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 10 | -------------------------------------------------------------------------------- /src/App2.vue: -------------------------------------------------------------------------------- 1 | 40 | 41 | 66 | -------------------------------------------------------------------------------- /src/assets/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/vue-crash-2024/d495fb10d91c10bf79cff0c665773ddad8e0fa65/src/assets/img/logo.png -------------------------------------------------------------------------------- /src/assets/main.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /src/components/BackButton.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 17 | -------------------------------------------------------------------------------- /src/components/Card.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 17 | -------------------------------------------------------------------------------- /src/components/Hero.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 32 | -------------------------------------------------------------------------------- /src/components/HomeCards.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 38 | -------------------------------------------------------------------------------- /src/components/JobListing.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 63 | -------------------------------------------------------------------------------- /src/components/JobListings.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 63 | -------------------------------------------------------------------------------- /src/components/Navbar.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 73 | -------------------------------------------------------------------------------- /src/jobs copy.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 1, 4 | "title": "Senior Vue Developer", 5 | "type": "Full-Time", 6 | "description": "We are seeking a talented Front-End Developer to join our team in Boston, MA. The ideal candidate will have strong skills in HTML, CSS, and JavaScript, with experience working with modern JavaScript frameworks such as Vue or Angular.", 7 | "location": "Boston, MA", 8 | "salary": "$70K - $80K", 9 | "company": { 10 | "name": "NewTek Solutions", 11 | "description": "NewTek Solutions is a leading technology company specializing in web development and digital solutions. We pride ourselves on delivering high-quality products and services to our clients while fostering a collaborative and innovative work environment.", 12 | "contactEmail": "contact@teksolutions.com", 13 | "contactPhone": "555-555-5555" 14 | } 15 | }, 16 | { 17 | "id": 2, 18 | "title": "Front-End Engineer (Vue)", 19 | "type": "Full-Time", 20 | "description": "Join our team as a Front-End Developer in sunny Miami, FL. We are looking for a motivated individual with a passion for crafting beautiful and responsive web applications. Experience with UI/UX design principles and a strong attention to detail are highly desirable.", 21 | "location": "Miami, FL", 22 | "salary": "$70K - $80K", 23 | "company": { 24 | "name": "Veneer Solutions", 25 | "description": "Veneer Solutions is a creative agency specializing in digital design and development. Our team is dedicated to pushing the boundaries of creativity and innovation to deliver exceptional results for our clients.", 26 | "contactEmail": "contact@loremipsum.com", 27 | "contactPhone": "555-555-5555" 28 | } 29 | }, 30 | { 31 | "id": 3, 32 | "title": "Vue.js Developer", 33 | "type": "Full-Time", 34 | "description": "Are you passionate about front-end development? Join our team in vibrant Brooklyn, NY, and work on exciting projects that make a difference. We offer competitive compensation and a collaborative work environment where your ideas are valued.", 35 | "location": "Brooklyn, NY", 36 | "salary": "$70K - $80K", 37 | "company": { 38 | "name": "Dolor Cloud", 39 | "description": "Dolor Cloud is a leading technology company specializing in digital solutions for businesses of all sizes. With a focus on innovation and customer satisfaction, we are committed to delivering cutting-edge products and services.", 40 | "contactEmail": "contact@dolorsitamet.com", 41 | "contactPhone": "555-555-5555" 42 | } 43 | }, 44 | { 45 | "id": 4, 46 | "title": "Vue Front-End Developer", 47 | "type": "Part-Time", 48 | "description": "Join our team as a Part-Time Front-End Developer in beautiful Pheonix, AZ. We are looking for a self-motivated individual with a passion for creating engaging user experiences. This position offers flexible hours and the opportunity to work remotely.", 49 | "location": "Pheonix, AZ", 50 | "salary": "$60K - $70K", 51 | "company": { 52 | "name": "Alpha Elite", 53 | "description": "Alpha Elite is a dynamic startup specializing in digital marketing and web development. We are committed to fostering a diverse and inclusive workplace where creativity and innovation thrive.", 54 | "contactEmail": "contact@adipisicingelit.com", 55 | "contactPhone": "555-555-5555" 56 | } 57 | }, 58 | { 59 | "id": 5, 60 | "title": "Full Stack Vue Developer", 61 | "type": "Full-Time", 62 | "description": "Exciting opportunity for a Full-Time Front-End Developer in bustling Atlanta, GA. We are seeking a talented individual with a passion for building elegant and scalable web applications. Join our team and make an impact!", 63 | "location": "Atlanta, GA", 64 | "salary": "$90K - $100K", 65 | "company": { 66 | "name": "Browning Technologies", 67 | "description": "Browning Technologies is a rapidly growing technology company specializing in e-commerce solutions. We offer a dynamic and collaborative work environment where employees are encouraged to think creatively and innovate.", 68 | "contactEmail": "contact@consecteturadipisicing.com", 69 | "contactPhone": "555-555-5555" 70 | } 71 | }, 72 | { 73 | "id": 6, 74 | "title": "Vue Native Developer", 75 | "type": "Full-Time", 76 | "description": "Join our team as a Front-End Developer in beautiful Portland, OR. We are looking for a skilled and enthusiastic individual to help us create innovative web solutions. Competitive salary and great benefits package available.", 77 | "location": "Portland, OR", 78 | "salary": "$100K - $110K", 79 | "company": { 80 | "name": "Port Solutions INC", 81 | "description": "Port Solutions is a leading technology company specializing in software development and digital marketing. We are committed to providing our clients with cutting-edge solutions and our employees with a supportive and rewarding work environment.", 82 | "contactEmail": "contact@ipsumlorem.com", 83 | "contactPhone": "555-555-5555" 84 | } 85 | } 86 | ] 87 | -------------------------------------------------------------------------------- /src/jobs.json: -------------------------------------------------------------------------------- 1 | { 2 | "jobs": [ 3 | { 4 | "title": "Senior Vue Dev", 5 | "type": "Full-Time", 6 | "location": "Boston, MA", 7 | "description": "We are seeking a talented Front-End Developer to join our team in Boston, MA. The ideal candidate will have strong skills in HTML, CSS, and JavaScript, with experience working with modern JavaScript frameworks such as Vue or Angular.", 8 | "salary": "$90K - $100K", 9 | "company": { 10 | "name": "NewTek Solutions", 11 | "description": "NewTek Solutions is a leading technology company specializing in web development and digital solutions. We pride ourselves on delivering high-quality products and services to our clients while fostering a collaborative and innovative work environment.", 12 | "contactEmail": "contact@teksolutions.com", 13 | "contactPhone": "555-555-5555" 14 | }, 15 | "id": "1" 16 | }, 17 | { 18 | "id": "2", 19 | "title": "Front-End Engineer (Vue)", 20 | "type": "Full-Time", 21 | "description": "Join our team as a Front-End Developer in sunny Miami, FL. We are looking for a motivated individual with a passion for crafting beautiful and responsive web applications. Experience with UI/UX design principles and a strong attention to detail are highly desirable.", 22 | "location": "Miami, FL", 23 | "salary": "$70K - $80K", 24 | "company": { 25 | "name": "Veneer Solutions", 26 | "description": "Veneer Solutions is a creative agency specializing in digital design and development. Our team is dedicated to pushing the boundaries of creativity and innovation to deliver exceptional results for our clients.", 27 | "contactEmail": "contact@loremipsum.com", 28 | "contactPhone": "555-555-5555" 29 | } 30 | }, 31 | { 32 | "id": "3", 33 | "title": "Vue.js Developer", 34 | "type": "Full-Time", 35 | "description": "Are you passionate about front-end development? Join our team in vibrant Brooklyn, NY, and work on exciting projects that make a difference. We offer competitive compensation and a collaborative work environment where your ideas are valued.", 36 | "location": "Brooklyn, NY", 37 | "salary": "$70K - $80K", 38 | "company": { 39 | "name": "Dolor Cloud", 40 | "description": "Dolor Cloud is a leading technology company specializing in digital solutions for businesses of all sizes. With a focus on innovation and customer satisfaction, we are committed to delivering cutting-edge products and services.", 41 | "contactEmail": "contact@dolorsitamet.com", 42 | "contactPhone": "555-555-5555" 43 | } 44 | }, 45 | { 46 | "id": "4", 47 | "title": "Vue Front-End Developer", 48 | "type": "Part-Time", 49 | "description": "Join our team as a Part-Time Front-End Developer in beautiful Pheonix, AZ. We are looking for a self-motivated individual with a passion for creating engaging user experiences. This position offers flexible hours and the opportunity to work remotely.", 50 | "location": "Pheonix, AZ", 51 | "salary": "$60K - $70K", 52 | "company": { 53 | "name": "Alpha Elite", 54 | "description": "Alpha Elite is a dynamic startup specializing in digital marketing and web development. We are committed to fostering a diverse and inclusive workplace where creativity and innovation thrive.", 55 | "contactEmail": "contact@adipisicingelit.com", 56 | "contactPhone": "555-555-5555" 57 | } 58 | }, 59 | { 60 | "id": "5", 61 | "title": "Full Stack Vue Developer", 62 | "type": "Full-Time", 63 | "description": "Exciting opportunity for a Full-Time Front-End Developer in bustling Atlanta, GA. We are seeking a talented individual with a passion for building elegant and scalable web applications. Join our team and make an impact!", 64 | "location": "Atlanta, GA", 65 | "salary": "$90K - $100K", 66 | "company": { 67 | "name": "Browning Technologies", 68 | "description": "Browning Technologies is a rapidly growing technology company specializing in e-commerce solutions. We offer a dynamic and collaborative work environment where employees are encouraged to think creatively and innovate.", 69 | "contactEmail": "contact@consecteturadipisicing.com", 70 | "contactPhone": "555-555-5555" 71 | } 72 | }, 73 | { 74 | "id": "6", 75 | "title": "Vue Native Developer", 76 | "type": "Full-Time", 77 | "description": "Join our team as a Front-End Developer in beautiful Portland, OR. We are looking for a skilled and enthusiastic individual to help us create innovative web solutions. Competitive salary and great benefits package available.", 78 | "location": "Portland, OR", 79 | "salary": "$100K - $110K", 80 | "company": { 81 | "name": "Port Solutions INC", 82 | "description": "Port Solutions is a leading technology company specializing in software development and digital marketing. We are committed to providing our clients with cutting-edge solutions and our employees with a supportive and rewarding work environment.", 83 | "contactEmail": "contact@ipsumlorem.com", 84 | "contactPhone": "555-555-5555" 85 | } 86 | } 87 | ] 88 | } -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import './assets/main.css'; 2 | import 'primeicons/primeicons.css'; 3 | import Toast from 'vue-toastification'; 4 | import 'vue-toastification/dist/index.css'; 5 | import router from './router'; 6 | 7 | import { createApp } from 'vue'; 8 | import App from './App.vue'; 9 | 10 | const app = createApp(App); 11 | 12 | app.use(router); 13 | app.use(Toast); 14 | 15 | app.mount('#app'); 16 | -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import { createRouter, createWebHistory } from 'vue-router'; 2 | import HomeView from '@/views/HomeView.vue'; 3 | import JobsView from '@/views/JobsView.vue'; 4 | import NotFoundView from '@/views/NotFoundView.vue'; 5 | import JobView from '@/views/JobView.vue'; 6 | import AddJobView from '@/views/AddJobView.vue'; 7 | import EditJobView from '@/views/EditJobView.vue'; 8 | 9 | const router = createRouter({ 10 | history: createWebHistory(import.meta.env.BASE_URL), 11 | routes: [ 12 | { 13 | path: '/', 14 | name: 'home', 15 | component: HomeView, 16 | }, 17 | { 18 | path: '/jobs', 19 | name: 'jobs', 20 | component: JobsView, 21 | }, 22 | { 23 | path: '/jobs/:id', 24 | name: 'job', 25 | component: JobView, 26 | }, 27 | { 28 | path: '/jobs/add', 29 | name: 'add-job', 30 | component: AddJobView, 31 | }, 32 | { 33 | path: '/jobs/edit/:id', 34 | name: 'edit-job', 35 | component: EditJobView, 36 | }, 37 | { 38 | path: '/:catchAll(.*)', 39 | name: 'not-found', 40 | component: NotFoundView, 41 | }, 42 | ], 43 | }); 44 | 45 | export default router; 46 | -------------------------------------------------------------------------------- /src/views/AddJobView.vue: -------------------------------------------------------------------------------- 1 | 48 | 49 | 219 | -------------------------------------------------------------------------------- /src/views/EditJobView.vue: -------------------------------------------------------------------------------- 1 | 79 | 80 | 250 | -------------------------------------------------------------------------------- /src/views/HomeView.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /src/views/JobView.vue: -------------------------------------------------------------------------------- 1 | 45 | 46 | 131 | -------------------------------------------------------------------------------- /src/views/JobsView.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /src/views/NotFoundView.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 17 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | export default { 3 | content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'], 4 | theme: { 5 | extend: { 6 | fontFamily: { 7 | sans: ['Poppins', 'sans-serif'], 8 | }, 9 | gridTemplateColumns: { 10 | '70/30': '70% 28%', 11 | }, 12 | }, 13 | }, 14 | variants: { 15 | extend: {}, 16 | }, 17 | plugins: [], 18 | }; 19 | -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import { fileURLToPath, URL } from 'node:url'; 2 | 3 | import { defineConfig } from 'vite'; 4 | import vue from '@vitejs/plugin-vue'; 5 | 6 | // https://vitejs.dev/config/ 7 | export default defineConfig({ 8 | plugins: [vue()], 9 | server: { 10 | port: 3000, 11 | proxy: { 12 | '/api': { 13 | target: 'http://localhost:8000', 14 | changeOrigin: true, 15 | rewrite: (path) => path.replace(/^\/api/, ''), 16 | }, 17 | }, 18 | }, 19 | resolve: { 20 | alias: { 21 | '@': fileURLToPath(new URL('./src', import.meta.url)), 22 | }, 23 | }, 24 | }); 25 | --------------------------------------------------------------------------------