├── README.md
├── appendix
├── components
│ └── MyComponent.vue
├── es6
│ ├── arrow_funcs.js
│ ├── arrow_funcs_jukebox_1.js
│ ├── arrow_funcs_jukebox_2.js
│ ├── const_let.js
│ ├── default_args.js
│ ├── destructuring_assignments.js
│ ├── enhanced_object_literals.js
│ ├── object_assign.js
│ ├── spread_operator_arrays.js
│ ├── template_literals_1.js
│ └── template_literals_2.js
└── store
│ └── simpleStore
│ ├── NumberDisplay.vue
│ ├── NumberSubmit.vue
│ └── store.js
├── calendar_app
├── .gitignore
├── README.md
├── babel.config.js
├── package-lock.json
├── package.json
├── public
│ ├── bulma
│ │ ├── bulma.css
│ │ └── bulma.css.map
│ ├── favicon.ico
│ ├── font-awesome
│ │ ├── HELP-US-OUT.txt
│ │ ├── css
│ │ │ ├── font-awesome.css
│ │ │ └── font-awesome.min.css
│ │ ├── fonts
│ │ │ ├── FontAwesome.otf
│ │ │ ├── fontawesome-webfont.eot
│ │ │ ├── fontawesome-webfont.svg
│ │ │ ├── fontawesome-webfont.ttf
│ │ │ ├── fontawesome-webfont.woff
│ │ │ └── fontawesome-webfont.woff2
│ │ ├── less
│ │ │ ├── animated.less
│ │ │ ├── bordered-pulled.less
│ │ │ ├── core.less
│ │ │ ├── fixed-width.less
│ │ │ ├── font-awesome.less
│ │ │ ├── icons.less
│ │ │ ├── larger.less
│ │ │ ├── list.less
│ │ │ ├── mixins.less
│ │ │ ├── path.less
│ │ │ ├── rotated-flipped.less
│ │ │ ├── screen-reader.less
│ │ │ ├── stacked.less
│ │ │ └── variables.less
│ │ └── scss
│ │ │ ├── _animated.scss
│ │ │ ├── _bordered-pulled.scss
│ │ │ ├── _core.scss
│ │ │ ├── _fixed-width.scss
│ │ │ ├── _icons.scss
│ │ │ ├── _larger.scss
│ │ │ ├── _list.scss
│ │ │ ├── _mixins.scss
│ │ │ ├── _path.scss
│ │ │ ├── _rotated-flipped.scss
│ │ │ ├── _screen-reader.scss
│ │ │ ├── _stacked.scss
│ │ │ ├── _variables.scss
│ │ │ └── font-awesome.scss
│ └── index.html
└── src
│ ├── app-1
│ ├── App.vue
│ ├── components
│ │ ├── CalendarEntry.vue
│ │ └── CalendarWeek.vue
│ └── seed.js
│ ├── app-2
│ ├── App.vue
│ ├── components
│ │ ├── CalendarDay.vue
│ │ ├── CalendarEntry.vue
│ │ └── CalendarWeek.vue
│ ├── seed.js
│ └── store.js
│ ├── app-3
│ ├── App.vue
│ ├── components
│ │ ├── CalendarDay.vue
│ │ ├── CalendarEntry.vue
│ │ ├── CalendarEvent.vue
│ │ └── CalendarWeek.vue
│ ├── seed.js
│ └── store.js
│ ├── app-4
│ ├── App.vue
│ ├── components
│ │ ├── CalendarDay.vue
│ │ ├── CalendarEntry.vue
│ │ ├── CalendarEvent.vue
│ │ └── CalendarWeek.vue
│ ├── seed.js
│ └── store.js
│ ├── app-5
│ ├── App.vue
│ ├── components
│ │ ├── CalendarDay.vue
│ │ ├── CalendarEntry.vue
│ │ ├── CalendarEvent.vue
│ │ └── CalendarWeek.vue
│ ├── seed.js
│ └── store.js
│ ├── app-6
│ ├── App.vue
│ ├── components
│ │ ├── CalendarDay.vue
│ │ ├── CalendarEntry.vue
│ │ ├── CalendarEvent.vue
│ │ └── CalendarWeek.vue
│ ├── seed.js
│ └── store.js
│ ├── app-7
│ ├── App.vue
│ ├── components
│ │ ├── CalendarDay.vue
│ │ ├── CalendarEntry.vue
│ │ ├── CalendarEvent.vue
│ │ └── CalendarWeek.vue
│ ├── seed.js
│ └── store.js
│ ├── app-complete
│ ├── App.vue
│ ├── components
│ │ ├── CalendarDay.vue
│ │ ├── CalendarEntry.vue
│ │ ├── CalendarEvent.vue
│ │ └── CalendarWeek.vue
│ ├── seed.js
│ └── store.js
│ ├── app
│ ├── App.vue
│ └── seed.js
│ └── main.js
├── custom_events
├── app-1
│ ├── index.html
│ └── main.js
├── app-2
│ ├── index.html
│ └── main.js
├── app-complete
│ ├── index.html
│ └── main.js
├── app
│ ├── index.html
│ └── main.js
└── public
│ └── styles.css
├── form_handling
├── 01-basic-button
│ ├── index.html
│ └── main.js
├── 02-basic-button
│ ├── index.html
│ └── main.js
├── 03-basic-input
│ ├── index.html
│ └── main.js
├── 04-data-input
│ ├── index.html
│ └── main.js
├── 05-data-input-list
│ ├── index.html
│ └── main.js
├── 06-data-input-multi
│ ├── index.html
│ └── main.js
├── 07-basic-form-validation
│ ├── index.html
│ └── main.js
├── 08-basic-field-validation
│ ├── index.html
│ └── main.js
├── 09-remote-persist
│ ├── index.html
│ └── main.js
├── 10-vuex-app
│ ├── index.html
│ ├── main.js
│ └── store.js
├── app
│ ├── index.html
│ └── main.js
└── public
│ └── semantic.min.css
├── index.json
├── my
└── upvote
│ └── index.html
├── package.json
├── routing
├── basics
│ ├── .gitignore
│ ├── README.md
│ ├── babel.config.js
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ └── styles.css
│ ├── src
│ │ ├── app
│ │ │ ├── app-1.js
│ │ │ ├── app-2.js
│ │ │ ├── app-3.js
│ │ │ ├── app-complete.js
│ │ │ └── app.js
│ │ └── main.js
│ └── vue.config.js
└── shopping_cart
│ ├── .gitignore
│ ├── README.md
│ ├── babel.config.js
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ ├── bulma
│ │ ├── bulma.css
│ │ └── bulma.css.map
│ ├── favicon.ico
│ ├── font-awesome
│ │ ├── HELP-US-OUT.txt
│ │ ├── css
│ │ │ ├── font-awesome.css
│ │ │ └── font-awesome.min.css
│ │ ├── fonts
│ │ │ ├── FontAwesome.otf
│ │ │ ├── fontawesome-webfont.eot
│ │ │ ├── fontawesome-webfont.svg
│ │ │ ├── fontawesome-webfont.ttf
│ │ │ ├── fontawesome-webfont.woff
│ │ │ └── fontawesome-webfont.woff2
│ │ ├── less
│ │ │ ├── animated.less
│ │ │ ├── bordered-pulled.less
│ │ │ ├── core.less
│ │ │ ├── fixed-width.less
│ │ │ ├── font-awesome.less
│ │ │ ├── icons.less
│ │ │ ├── larger.less
│ │ │ ├── list.less
│ │ │ ├── mixins.less
│ │ │ ├── path.less
│ │ │ ├── rotated-flipped.less
│ │ │ ├── screen-reader.less
│ │ │ ├── stacked.less
│ │ │ └── variables.less
│ │ └── scss
│ │ │ ├── _animated.scss
│ │ │ ├── _bordered-pulled.scss
│ │ │ ├── _core.scss
│ │ │ ├── _fixed-width.scss
│ │ │ ├── _icons.scss
│ │ │ ├── _larger.scss
│ │ │ ├── _list.scss
│ │ │ ├── _mixins.scss
│ │ │ ├── _path.scss
│ │ │ ├── _rotated-flipped.scss
│ │ │ ├── _screen-reader.scss
│ │ │ ├── _stacked.scss
│ │ │ ├── _variables.scss
│ │ │ └── font-awesome.scss
│ └── index.html
│ ├── server-cart-data.json
│ ├── server-product-data.json
│ ├── server.js
│ ├── src
│ ├── app-1
│ │ ├── App.vue
│ │ ├── assets
│ │ │ ├── cap.png
│ │ │ ├── hoodie.png
│ │ │ ├── jacket.png
│ │ │ └── tee.png
│ │ ├── components
│ │ │ ├── NotFound.vue
│ │ │ ├── cart
│ │ │ │ ├── CartList.vue
│ │ │ │ └── CartListItem.vue
│ │ │ └── product
│ │ │ │ ├── ProductList.vue
│ │ │ │ └── ProductListItem.vue
│ │ ├── router
│ │ │ └── index.js
│ │ └── store
│ │ │ ├── index.js
│ │ │ └── modules
│ │ │ ├── cart
│ │ │ └── index.js
│ │ │ └── product
│ │ │ └── index.js
│ ├── app-2
│ │ ├── App.vue
│ │ ├── assets
│ │ │ ├── cap.png
│ │ │ ├── hoodie.png
│ │ │ ├── jacket.png
│ │ │ └── tee.png
│ │ ├── components
│ │ │ ├── NotFound.vue
│ │ │ ├── cart
│ │ │ │ ├── CartList.vue
│ │ │ │ └── CartListItem.vue
│ │ │ └── product
│ │ │ │ ├── ProductItem.vue
│ │ │ │ ├── ProductList.vue
│ │ │ │ └── ProductListItem.vue
│ │ ├── router
│ │ │ └── index.js
│ │ └── store
│ │ │ ├── index.js
│ │ │ └── modules
│ │ │ ├── cart
│ │ │ └── index.js
│ │ │ └── product
│ │ │ └── index.js
│ ├── app-3
│ │ ├── App.vue
│ │ ├── assets
│ │ │ ├── cap.png
│ │ │ ├── hoodie.png
│ │ │ ├── jacket.png
│ │ │ └── tee.png
│ │ ├── components
│ │ │ ├── NotFound.vue
│ │ │ ├── cart
│ │ │ │ ├── CartList.vue
│ │ │ │ └── CartListItem.vue
│ │ │ ├── login
│ │ │ │ └── LoginBox.vue
│ │ │ └── product
│ │ │ │ ├── ProductItem.vue
│ │ │ │ ├── ProductList.vue
│ │ │ │ └── ProductListItem.vue
│ │ ├── router
│ │ │ └── index.js
│ │ └── store
│ │ │ ├── index.js
│ │ │ └── modules
│ │ │ ├── cart
│ │ │ └── index.js
│ │ │ ├── login
│ │ │ └── index.js
│ │ │ └── product
│ │ │ └── index.js
│ ├── app-complete
│ │ ├── App.vue
│ │ ├── assets
│ │ │ ├── cap.png
│ │ │ ├── hoodie.png
│ │ │ ├── jacket.png
│ │ │ └── tee.png
│ │ ├── components
│ │ │ ├── NotFound.vue
│ │ │ ├── cart
│ │ │ │ ├── CartList.vue
│ │ │ │ └── CartListItem.vue
│ │ │ ├── login
│ │ │ │ └── LoginBox.vue
│ │ │ └── product
│ │ │ │ ├── ProductItem.vue
│ │ │ │ ├── ProductList.vue
│ │ │ │ └── ProductListItem.vue
│ │ ├── router
│ │ │ └── index.js
│ │ └── store
│ │ │ ├── index.js
│ │ │ └── modules
│ │ │ ├── cart
│ │ │ └── index.js
│ │ │ ├── login
│ │ │ └── index.js
│ │ │ └── product
│ │ │ └── index.js
│ ├── app
│ │ ├── App.vue
│ │ ├── assets
│ │ │ ├── cap.png
│ │ │ ├── hoodie.png
│ │ │ ├── jacket.png
│ │ │ └── tee.png
│ │ ├── components
│ │ │ ├── cart
│ │ │ │ ├── CartList.vue
│ │ │ │ └── CartListItem.vue
│ │ │ └── product
│ │ │ │ ├── ProductList.vue
│ │ │ │ └── ProductListItem.vue
│ │ └── store
│ │ │ ├── index.js
│ │ │ └── modules
│ │ │ ├── cart
│ │ │ └── index.js
│ │ │ └── product
│ │ │ └── index.js
│ └── main.js
│ └── vue.config.js
├── testing
├── basics
│ ├── .gitignore
│ ├── README.md
│ ├── babel.config.js
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ └── semantic.min.css
│ ├── src
│ │ ├── App.vue
│ │ └── main.js
│ └── tests
│ │ └── unit
│ │ ├── .eslintrc.js
│ │ ├── App.1.spec.js
│ │ ├── App.2.spec.js
│ │ ├── App.3.spec.js
│ │ ├── App.4.spec.js
│ │ ├── App.5.spec.js
│ │ ├── App.complete.spec.js
│ │ └── App.spec.js
└── weather
│ ├── .gitignore
│ ├── README.md
│ ├── babel.config.js
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ ├── bulma.css
│ ├── favicon.ico
│ └── index.html
│ ├── server.js
│ ├── src
│ ├── App.vue
│ ├── assets
│ │ ├── c.png
│ │ ├── h.png
│ │ ├── hc.png
│ │ ├── hr.png
│ │ ├── lc.png
│ │ ├── lr.png
│ │ ├── s.png
│ │ ├── sl.png
│ │ ├── sn.png
│ │ └── t.png
│ ├── components
│ │ ├── HomeContainer.vue
│ │ ├── NotFoundContainer.vue
│ │ └── WeatherContainer.vue
│ ├── main.js
│ ├── router.js
│ └── store.js
│ ├── tests
│ └── unit
│ │ ├── .eslintrc.js
│ │ ├── weather-1
│ │ ├── App.spec.js
│ │ └── components
│ │ │ ├── HomeContainer.spec.js
│ │ │ ├── NotFoundContainer.spec.js
│ │ │ └── WeatherContainer.spec.js
│ │ ├── weather-2
│ │ ├── App.spec.js
│ │ └── components
│ │ │ ├── HomeContainer.spec.js
│ │ │ ├── NotFoundContainer.spec.js
│ │ │ └── WeatherContainer.spec.js
│ │ ├── weather-3
│ │ ├── App.spec.js
│ │ └── components
│ │ │ ├── HomeContainer.spec.js
│ │ │ ├── NotFoundContainer.spec.js
│ │ │ └── WeatherContainer.spec.js
│ │ ├── weather-complete
│ │ ├── App.spec.js
│ │ └── components
│ │ │ ├── HomeContainer.spec.js
│ │ │ ├── NotFoundContainer.spec.js
│ │ │ └── WeatherContainer.spec.js
│ │ └── weather
│ │ ├── App.spec.js
│ │ └── components
│ │ ├── HomeContainer.spec.js
│ │ ├── NotFoundContainer.spec.js
│ │ └── WeatherContainer.spec.js
│ └── vue.config.js
├── upvote
├── app
│ ├── index.html
│ ├── main.js
│ └── seed.js
├── app_1
│ ├── index.html
│ ├── main.js
│ └── seed.js
├── app_2
│ ├── index.html
│ ├── main.js
│ └── seed.js
├── app_3
│ ├── index.html
│ ├── main.js
│ └── seed.js
├── app_4
│ ├── index.html
│ ├── main.js
│ └── seed.js
├── app_5
│ ├── index.html
│ ├── main.js
│ └── seed.js
├── app_complete
│ ├── index.html
│ ├── main.js
│ └── seed.js
└── public
│ ├── images
│ ├── avatars
│ │ ├── daniel.jpg
│ │ ├── kristy.png
│ │ ├── molly.png
│ │ └── veronika.jpg
│ └── submissions
│ │ ├── image-aqua.png
│ │ ├── image-rose.png
│ │ ├── image-steel.png
│ │ └── image-yellow.png
│ └── styles.css
└── vuex
├── note_taking
├── app-complete
│ ├── index.html
│ └── main.js
├── app
│ ├── index.html
│ └── main.js
└── public
│ └── styles.css
└── shopping_cart
├── .gitignore
├── README.md
├── babel.config.js
├── package-lock.json
├── package.json
├── public
├── bulma
│ ├── bulma.css
│ └── bulma.css.map
├── favicon.ico
├── font-awesome
│ ├── HELP-US-OUT.txt
│ ├── css
│ │ ├── font-awesome.css
│ │ └── font-awesome.min.css
│ ├── fonts
│ │ ├── FontAwesome.otf
│ │ ├── fontawesome-webfont.eot
│ │ ├── fontawesome-webfont.svg
│ │ ├── fontawesome-webfont.ttf
│ │ ├── fontawesome-webfont.woff
│ │ └── fontawesome-webfont.woff2
│ ├── less
│ │ ├── animated.less
│ │ ├── bordered-pulled.less
│ │ ├── core.less
│ │ ├── fixed-width.less
│ │ ├── font-awesome.less
│ │ ├── icons.less
│ │ ├── larger.less
│ │ ├── list.less
│ │ ├── mixins.less
│ │ ├── path.less
│ │ ├── rotated-flipped.less
│ │ ├── screen-reader.less
│ │ ├── stacked.less
│ │ └── variables.less
│ └── scss
│ │ ├── _animated.scss
│ │ ├── _bordered-pulled.scss
│ │ ├── _core.scss
│ │ ├── _fixed-width.scss
│ │ ├── _icons.scss
│ │ ├── _larger.scss
│ │ ├── _list.scss
│ │ ├── _mixins.scss
│ │ ├── _path.scss
│ │ ├── _rotated-flipped.scss
│ │ ├── _screen-reader.scss
│ │ ├── _stacked.scss
│ │ ├── _variables.scss
│ │ └── font-awesome.scss
└── index.html
├── server-cart-data.json
├── server-product-data.json
├── server.js
├── src
├── app-1
│ ├── App.vue
│ ├── components
│ │ ├── cart
│ │ │ └── CartList.vue
│ │ └── product
│ │ │ └── ProductList.vue
│ └── store
│ │ ├── index.js
│ │ └── modules
│ │ ├── cart
│ │ └── index.js
│ │ └── product
│ │ └── index.js
├── app-2
│ ├── App.vue
│ ├── components
│ │ ├── cart
│ │ │ └── CartList.vue
│ │ └── product
│ │ │ ├── ProductList.vue
│ │ │ └── ProductListItem.vue
│ └── store
│ │ ├── index.js
│ │ └── modules
│ │ ├── cart
│ │ └── index.js
│ │ └── product
│ │ └── index.js
├── app-3
│ ├── App.vue
│ ├── components
│ │ ├── cart
│ │ │ ├── CartList.vue
│ │ │ └── CartListItem.vue
│ │ └── product
│ │ │ ├── ProductList.vue
│ │ │ └── ProductListItem.vue
│ └── store
│ │ ├── index.js
│ │ └── modules
│ │ ├── cart
│ │ └── index.js
│ │ └── product
│ │ └── index.js
├── app-complete
│ ├── App.vue
│ ├── components
│ │ ├── cart
│ │ │ ├── CartList.vue
│ │ │ └── CartListItem.vue
│ │ └── product
│ │ │ ├── ProductList.vue
│ │ │ └── ProductListItem.vue
│ └── store
│ │ ├── index.js
│ │ └── modules
│ │ ├── cart
│ │ └── index.js
│ │ └── product
│ │ └── index.js
├── app
│ ├── App.vue
│ └── components
│ │ ├── cart
│ │ └── CartList.vue
│ │ └── product
│ │ └── ProductList.vue
└── main.js
└── vue.config.js
/README.md:
--------------------------------------------------------------------------------
1 | # Code examples for Fullstack Vue
2 |
3 | ## Setup
4 |
5 | Please refer to the second chapter in the book for instructions on setting up your environment with Node & npm.
6 |
7 | ## Installing packages for all projects
8 |
9 | You can install all the packages for all the projects up front, saving you time in the future. To do so, from this directory:
10 |
11 | ```
12 | npm i
13 | npm run install-all
14 | ```
15 |
16 | Unless you have a quantum computer connected directly to an Amazon data center, this task will take a long time to complete.
17 |
18 | ## Running the code
19 |
20 | See the respective `README.md` for each project.
21 |
--------------------------------------------------------------------------------
/appendix/components/MyComponent.vue:
--------------------------------------------------------------------------------
1 |
2 | {{ getGreeting }}
3 | This is the Hello World component.
4 |
5 |
6 |
21 |
22 |
28 |
--------------------------------------------------------------------------------
/appendix/es6/arrow_funcs.js:
--------------------------------------------------------------------------------
1 | const cities = [
2 | { name: 'Cairo', pop: 7764700 },
3 | { name: 'Lagos', pop: 8029200 },
4 | ];
5 |
6 | const formattedPopulations = cities.map((city) => {
7 | const popMM = (city.pop / 1000000).toFixed(2);
8 | return popMM + ' million';
9 | });
10 | console.log(formattedPopulations);
11 | // -> [ "7.76 million", "8.03 million" ]
12 |
13 | const formattedPopulations2 = cities.map((city) => (
14 | (city.pop / 1000000).toFixed(2) + ' million'
15 | ));
16 |
17 | const pops = cities.map(city => city.pop);
18 | console.log(pops);
19 | // [ 7764700, 8029200 ]
20 |
21 | const popsNoArrow = cities.map(function(city) { return city.pop });
22 |
--------------------------------------------------------------------------------
/appendix/es6/arrow_funcs_jukebox_1.js:
--------------------------------------------------------------------------------
1 | function printSong() {
2 | console.log("Oops - The Global Object");
3 | }
4 |
5 | const jukebox = {
6 | songs: [
7 | {
8 | title: "Wanna Be Startin' Somethin'",
9 | artist: "Michael Jackson",
10 | },
11 | {
12 | title: "Superstar",
13 | artist: "Madonna",
14 | },
15 | ],
16 | printSong: function (song) {
17 | console.log(song.title + " - " + song.artist);
18 | },
19 | printSongs: function () {
20 | // `this` bound to the object (OK)
21 | this.songs.forEach(function(song) {
22 | // `this` bound to global object (bad)
23 | this.printSong(song);
24 | });
25 | },
26 | }
27 |
28 | jukebox.printSongs();
29 | // > "Oops - The Global Object"
30 | // > "Oops - The Global Object"
31 |
--------------------------------------------------------------------------------
/appendix/es6/arrow_funcs_jukebox_2.js:
--------------------------------------------------------------------------------
1 | function printSong() {
2 | console.log("Oops - The Global Object");
3 | }
4 |
5 | const jukebox = {
6 | songs: [
7 | {
8 | title: "Wanna Be Startin' Somethin'",
9 | artist: "Michael Jackson",
10 | },
11 | {
12 | title: "Superstar",
13 | artist: "Madonna",
14 | },
15 | ],
16 | printSong: function (song) {
17 | console.log(song.title + " - " + song.artist);
18 | },
19 | printSongs: function () {
20 | this.songs.forEach((song) => {
21 | // `this` bound to same `this` as `printSongs()` (`jukebox`)
22 | this.printSong(song);
23 | });
24 | },
25 | }
26 |
27 | jukebox.printSongs();
28 | // > "Wanna Be Startin' Somethin' - Michael Jackson"
29 | // > "Superstar - Madonna"
30 |
--------------------------------------------------------------------------------
/appendix/es6/const_let.js:
--------------------------------------------------------------------------------
1 | var myVariable = 5;
2 |
--------------------------------------------------------------------------------
/appendix/es6/default_args.js:
--------------------------------------------------------------------------------
1 | function divide(a, b) {
2 | // Default divisor to `1`
3 | const divisor = typeof b === 'undefined' ? 1 : b;
4 |
5 | return a / divisor;
6 | }
7 |
8 | function divide(a, b = 1) {
9 | return a / b;
10 | }
11 |
12 | divide(14, 2);
13 | // => 7
14 | divide(14, undefined);
15 | // => 14
16 | divide(14);
17 | // => 14
18 |
19 | divide(14, null); // `null` is used as divisor
20 | // => Infinity // 14 / null
21 |
--------------------------------------------------------------------------------
/appendix/es6/destructuring_assignments.js:
--------------------------------------------------------------------------------
1 | var fruits = [ 'apples', 'bananas', 'oranges' ];
2 | var fruit1 = fruits[0];
3 | var fruit2 = fruits[1];
4 |
5 | const [ veg1, veg2 ] = [ 'asparagus', 'broccoli', 'onion' ];
6 | console.log(veg1); // -> 'asparagus'
7 | console.log(veg2); // -> 'broccoli'
8 |
9 | const smoothie = {
10 | fats: [ 'avocado', 'peanut butter', 'greek yogurt' ],
11 | liquids: [ 'almond milk' ],
12 | greens: [ 'spinach' ],
13 | fruits: [ 'blueberry', 'banana' ],
14 | };
15 |
16 | const { liquids, fruits } = smoothie;
17 |
18 | console.log(liquids); // -> [ 'almond milk' ]
19 | console.log(fruits); // -> [ 'blueberry', 'banana' ]
20 |
21 | const containsSpinach = ({ greens }) => {
22 | if (greens.find(g => g === 'spinach')) {
23 | return true;
24 | } else {
25 | return false;
26 | }
27 | };
28 |
29 | containsSpinach(smoothie); // -> true
30 |
--------------------------------------------------------------------------------
/appendix/es6/enhanced_object_literals.js:
--------------------------------------------------------------------------------
1 | const explicit = {
2 | getState: getState,
3 | dispatch: dispatch,
4 | };
5 |
6 | const implicit = {
7 | getState,
8 | dispatch,
9 | };
10 |
--------------------------------------------------------------------------------
/appendix/es6/object_assign.js:
--------------------------------------------------------------------------------
1 | const coffee = { };
2 | const noCream = { cream: false };
3 | const noMilk = { milk: false };
4 | Object.assign(coffee, noCream);
5 | // coffee is now: `{ cream: false }`
6 | Object.assign(coffee, noMilk);
7 | // coffee is now: `{ cream: false, milk: false }`
8 |
9 | const coffeeWithMilk = Object.assign({}, coffee, { milk: true });
10 | // coffeeWithMilk is: `{ cream: false, milk: true }`
11 | // coffee was not modified: `{ cream: false, milk: false }`
12 |
--------------------------------------------------------------------------------
/appendix/es6/spread_operator_arrays.js:
--------------------------------------------------------------------------------
1 | const a = [ 1, 2, 3 ];
2 | const b = [ 4, 5, 6 ];
3 | const c = [ ...a, ...b, 7, 8, 9 ];
4 |
5 | console.log(c); // -> [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
6 |
7 | const d = [ a, b, 7, 8, 9 ];
8 | console.log(d); // -> [ [ 1, 2, 3 ], [ 4, 5, 6 ], 7, 8, 9 ]
9 |
--------------------------------------------------------------------------------
/appendix/es6/template_literals_1.js:
--------------------------------------------------------------------------------
1 |
2 | var greeting = 'Hello, ' + user + '! It is ' + degF + ' degrees outside.';
3 |
--------------------------------------------------------------------------------
/appendix/es6/template_literals_2.js:
--------------------------------------------------------------------------------
1 |
2 | const greeting = `Hello, ${user}! It is ${degF} degrees outside.`;
3 |
--------------------------------------------------------------------------------
/appendix/store/simpleStore/NumberDisplay.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ storeState.numbers }}
4 |
5 |
6 |
7 |
19 |
--------------------------------------------------------------------------------
/appendix/store/simpleStore/NumberSubmit.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
25 |
--------------------------------------------------------------------------------
/appendix/store/simpleStore/store.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 |
3 | export const store = {
4 | state: {
5 | numbers: [1, 2, 3]
6 | },
7 | pushNewNumber(newNumberString) {
8 | this.state.numbers.push(Number(newNumberString));
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/calendar_app/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 | # local env files
6 | .env.local
7 | .env.*.local
8 |
9 | # Log files
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 | *.suo
18 | *.ntvs*
19 | *.njsproj
20 | *.sln
21 | *.sw*
22 |
--------------------------------------------------------------------------------
/calendar_app/README.md:
--------------------------------------------------------------------------------
1 | # Fullstack Vue
2 |
3 | ## Single-file components - Calendar App
4 |
5 | 1. Ensure you have `npm` installed.
6 |
7 | 2. Install the dependencies
8 |
9 | ````
10 | npm install
11 | ````
12 |
13 | 3. Boot the app
14 |
15 | ````
16 | npm run serve
17 | ````
18 |
19 | The server is now running - watch the console output for instructions, but by default, your server is now running (with hot reload) at [http://localhost:8080/](http://localhost:8080/)
--------------------------------------------------------------------------------
/calendar_app/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/calendar_app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "calendar_app",
3 | "description": "Project Two: Calendar App",
4 | "version": "1.0.0",
5 | "author": "Fullstack.io",
6 | "private": true,
7 | "scripts": {
8 | "serve": "vue-cli-service serve",
9 | "build": "vue-cli-service build",
10 | "lint": "vue-cli-service lint"
11 | },
12 | "dependencies": {
13 | "vue": "^2.5.17"
14 | },
15 | "devDependencies": {
16 | "@vue/cli-service": "^3.0.0",
17 | "@vue/cli-plugin-babel": "^3.0.0",
18 | "@vue/cli-plugin-eslint": "^3.0.0",
19 | "node-sass": "^4.9.0",
20 | "sass-loader": "^7.0.1",
21 | "vue-template-compiler": "^2.5.17"
22 | },
23 | "eslintConfig": {
24 | "root": true,
25 | "env": {
26 | "node": true
27 | },
28 | "extends": [
29 | "plugin:vue/essential",
30 | "eslint:recommended"
31 | ],
32 | "rules": {},
33 | "parserOptions": {
34 | "parser": "babel-eslint"
35 | }
36 | },
37 | "postcss": {
38 | "plugins": {
39 | "autoprefixer": {}
40 | }
41 | },
42 | "browserslist": [
43 | "> 1%",
44 | "last 2 versions",
45 | "not ie <= 8"
46 | ]
47 | }
48 |
--------------------------------------------------------------------------------
/calendar_app/public/bulma/bulma.css.map:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/calendar_app/public/bulma/bulma.css.map
--------------------------------------------------------------------------------
/calendar_app/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/calendar_app/public/favicon.ico
--------------------------------------------------------------------------------
/calendar_app/public/font-awesome/HELP-US-OUT.txt:
--------------------------------------------------------------------------------
1 | I hope you love Font Awesome. If you've found it useful, please do me a favor and check out my latest project,
2 | Fort Awesome (https://fortawesome.com). It makes it easy to put the perfect icons on your website. Choose from our awesome,
3 | comprehensive icon sets or copy and paste your own.
4 |
5 | Please. Check it out.
6 |
7 | -Dave Gandy
8 |
--------------------------------------------------------------------------------
/calendar_app/public/font-awesome/fonts/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/calendar_app/public/font-awesome/fonts/FontAwesome.otf
--------------------------------------------------------------------------------
/calendar_app/public/font-awesome/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/calendar_app/public/font-awesome/fonts/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/calendar_app/public/font-awesome/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/calendar_app/public/font-awesome/fonts/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/calendar_app/public/font-awesome/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/calendar_app/public/font-awesome/fonts/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/calendar_app/public/font-awesome/fonts/fontawesome-webfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/calendar_app/public/font-awesome/fonts/fontawesome-webfont.woff2
--------------------------------------------------------------------------------
/calendar_app/public/font-awesome/less/animated.less:
--------------------------------------------------------------------------------
1 | // Animated Icons
2 | // --------------------------
3 |
4 | .@{fa-css-prefix}-spin {
5 | -webkit-animation: fa-spin 2s infinite linear;
6 | animation: fa-spin 2s infinite linear;
7 | }
8 |
9 | .@{fa-css-prefix}-pulse {
10 | -webkit-animation: fa-spin 1s infinite steps(8);
11 | animation: fa-spin 1s infinite steps(8);
12 | }
13 |
14 | @-webkit-keyframes fa-spin {
15 | 0% {
16 | -webkit-transform: rotate(0deg);
17 | transform: rotate(0deg);
18 | }
19 | 100% {
20 | -webkit-transform: rotate(359deg);
21 | transform: rotate(359deg);
22 | }
23 | }
24 |
25 | @keyframes fa-spin {
26 | 0% {
27 | -webkit-transform: rotate(0deg);
28 | transform: rotate(0deg);
29 | }
30 | 100% {
31 | -webkit-transform: rotate(359deg);
32 | transform: rotate(359deg);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/calendar_app/public/font-awesome/less/bordered-pulled.less:
--------------------------------------------------------------------------------
1 | // Bordered & Pulled
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-border {
5 | padding: .2em .25em .15em;
6 | border: solid .08em @fa-border-color;
7 | border-radius: .1em;
8 | }
9 |
10 | .@{fa-css-prefix}-pull-left { float: left; }
11 | .@{fa-css-prefix}-pull-right { float: right; }
12 |
13 | .@{fa-css-prefix} {
14 | &.@{fa-css-prefix}-pull-left { margin-right: .3em; }
15 | &.@{fa-css-prefix}-pull-right { margin-left: .3em; }
16 | }
17 |
18 | /* Deprecated as of 4.4.0 */
19 | .pull-right { float: right; }
20 | .pull-left { float: left; }
21 |
22 | .@{fa-css-prefix} {
23 | &.pull-left { margin-right: .3em; }
24 | &.pull-right { margin-left: .3em; }
25 | }
26 |
--------------------------------------------------------------------------------
/calendar_app/public/font-awesome/less/core.less:
--------------------------------------------------------------------------------
1 | // Base Class Definition
2 | // -------------------------
3 |
4 | .@{fa-css-prefix} {
5 | display: inline-block;
6 | font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration
7 | font-size: inherit; // can't have font-size inherit on line above, so need to override
8 | text-rendering: auto; // optimizelegibility throws things off #1094
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/calendar_app/public/font-awesome/less/fixed-width.less:
--------------------------------------------------------------------------------
1 | // Fixed Width Icons
2 | // -------------------------
3 | .@{fa-css-prefix}-fw {
4 | width: (18em / 14);
5 | text-align: center;
6 | }
7 |
--------------------------------------------------------------------------------
/calendar_app/public/font-awesome/less/font-awesome.less:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
4 | */
5 |
6 | @import "variables.less";
7 | @import "mixins.less";
8 | @import "path.less";
9 | @import "core.less";
10 | @import "larger.less";
11 | @import "fixed-width.less";
12 | @import "list.less";
13 | @import "bordered-pulled.less";
14 | @import "animated.less";
15 | @import "rotated-flipped.less";
16 | @import "stacked.less";
17 | @import "icons.less";
18 | @import "screen-reader.less";
19 |
--------------------------------------------------------------------------------
/calendar_app/public/font-awesome/less/larger.less:
--------------------------------------------------------------------------------
1 | // Icon Sizes
2 | // -------------------------
3 |
4 | /* makes the font 33% larger relative to the icon container */
5 | .@{fa-css-prefix}-lg {
6 | font-size: (4em / 3);
7 | line-height: (3em / 4);
8 | vertical-align: -15%;
9 | }
10 | .@{fa-css-prefix}-2x { font-size: 2em; }
11 | .@{fa-css-prefix}-3x { font-size: 3em; }
12 | .@{fa-css-prefix}-4x { font-size: 4em; }
13 | .@{fa-css-prefix}-5x { font-size: 5em; }
14 |
--------------------------------------------------------------------------------
/calendar_app/public/font-awesome/less/list.less:
--------------------------------------------------------------------------------
1 | // List Icons
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-ul {
5 | padding-left: 0;
6 | margin-left: @fa-li-width;
7 | list-style-type: none;
8 | > li { position: relative; }
9 | }
10 | .@{fa-css-prefix}-li {
11 | position: absolute;
12 | left: -@fa-li-width;
13 | width: @fa-li-width;
14 | top: (2em / 14);
15 | text-align: center;
16 | &.@{fa-css-prefix}-lg {
17 | left: (-@fa-li-width + (4em / 14));
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/calendar_app/public/font-awesome/less/path.less:
--------------------------------------------------------------------------------
1 | /* FONT PATH
2 | * -------------------------- */
3 |
4 | @font-face {
5 | font-family: 'FontAwesome';
6 | src: url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}');
7 | src: url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype'),
8 | url('@{fa-font-path}/fontawesome-webfont.woff2?v=@{fa-version}') format('woff2'),
9 | url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff'),
10 | url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype'),
11 | url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg');
12 | // src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
13 | font-weight: normal;
14 | font-style: normal;
15 | }
16 |
--------------------------------------------------------------------------------
/calendar_app/public/font-awesome/less/rotated-flipped.less:
--------------------------------------------------------------------------------
1 | // Rotated & Flipped Icons
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); }
5 | .@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); }
6 | .@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); }
7 |
8 | .@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); }
9 | .@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); }
10 |
11 | // Hook for IE8-9
12 | // -------------------------
13 |
14 | :root .@{fa-css-prefix}-rotate-90,
15 | :root .@{fa-css-prefix}-rotate-180,
16 | :root .@{fa-css-prefix}-rotate-270,
17 | :root .@{fa-css-prefix}-flip-horizontal,
18 | :root .@{fa-css-prefix}-flip-vertical {
19 | filter: none;
20 | }
21 |
--------------------------------------------------------------------------------
/calendar_app/public/font-awesome/less/screen-reader.less:
--------------------------------------------------------------------------------
1 | // Screen Readers
2 | // -------------------------
3 |
4 | .sr-only { .sr-only(); }
5 | .sr-only-focusable { .sr-only-focusable(); }
6 |
--------------------------------------------------------------------------------
/calendar_app/public/font-awesome/less/stacked.less:
--------------------------------------------------------------------------------
1 | // Stacked Icons
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-stack {
5 | position: relative;
6 | display: inline-block;
7 | width: 2em;
8 | height: 2em;
9 | line-height: 2em;
10 | vertical-align: middle;
11 | }
12 | .@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x {
13 | position: absolute;
14 | left: 0;
15 | width: 100%;
16 | text-align: center;
17 | }
18 | .@{fa-css-prefix}-stack-1x { line-height: inherit; }
19 | .@{fa-css-prefix}-stack-2x { font-size: 2em; }
20 | .@{fa-css-prefix}-inverse { color: @fa-inverse; }
21 |
--------------------------------------------------------------------------------
/calendar_app/public/font-awesome/scss/_animated.scss:
--------------------------------------------------------------------------------
1 | // Spinning Icons
2 | // --------------------------
3 |
4 | .#{$fa-css-prefix}-spin {
5 | -webkit-animation: fa-spin 2s infinite linear;
6 | animation: fa-spin 2s infinite linear;
7 | }
8 |
9 | .#{$fa-css-prefix}-pulse {
10 | -webkit-animation: fa-spin 1s infinite steps(8);
11 | animation: fa-spin 1s infinite steps(8);
12 | }
13 |
14 | @-webkit-keyframes fa-spin {
15 | 0% {
16 | -webkit-transform: rotate(0deg);
17 | transform: rotate(0deg);
18 | }
19 | 100% {
20 | -webkit-transform: rotate(359deg);
21 | transform: rotate(359deg);
22 | }
23 | }
24 |
25 | @keyframes fa-spin {
26 | 0% {
27 | -webkit-transform: rotate(0deg);
28 | transform: rotate(0deg);
29 | }
30 | 100% {
31 | -webkit-transform: rotate(359deg);
32 | transform: rotate(359deg);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/calendar_app/public/font-awesome/scss/_bordered-pulled.scss:
--------------------------------------------------------------------------------
1 | // Bordered & Pulled
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-border {
5 | padding: .2em .25em .15em;
6 | border: solid .08em $fa-border-color;
7 | border-radius: .1em;
8 | }
9 |
10 | .#{$fa-css-prefix}-pull-left { float: left; }
11 | .#{$fa-css-prefix}-pull-right { float: right; }
12 |
13 | .#{$fa-css-prefix} {
14 | &.#{$fa-css-prefix}-pull-left { margin-right: .3em; }
15 | &.#{$fa-css-prefix}-pull-right { margin-left: .3em; }
16 | }
17 |
18 | /* Deprecated as of 4.4.0 */
19 | .pull-right { float: right; }
20 | .pull-left { float: left; }
21 |
22 | .#{$fa-css-prefix} {
23 | &.pull-left { margin-right: .3em; }
24 | &.pull-right { margin-left: .3em; }
25 | }
26 |
--------------------------------------------------------------------------------
/calendar_app/public/font-awesome/scss/_core.scss:
--------------------------------------------------------------------------------
1 | // Base Class Definition
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix} {
5 | display: inline-block;
6 | font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration
7 | font-size: inherit; // can't have font-size inherit on line above, so need to override
8 | text-rendering: auto; // optimizelegibility throws things off #1094
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/calendar_app/public/font-awesome/scss/_fixed-width.scss:
--------------------------------------------------------------------------------
1 | // Fixed Width Icons
2 | // -------------------------
3 | .#{$fa-css-prefix}-fw {
4 | width: (18em / 14);
5 | text-align: center;
6 | }
7 |
--------------------------------------------------------------------------------
/calendar_app/public/font-awesome/scss/_larger.scss:
--------------------------------------------------------------------------------
1 | // Icon Sizes
2 | // -------------------------
3 |
4 | /* makes the font 33% larger relative to the icon container */
5 | .#{$fa-css-prefix}-lg {
6 | font-size: (4em / 3);
7 | line-height: (3em / 4);
8 | vertical-align: -15%;
9 | }
10 | .#{$fa-css-prefix}-2x { font-size: 2em; }
11 | .#{$fa-css-prefix}-3x { font-size: 3em; }
12 | .#{$fa-css-prefix}-4x { font-size: 4em; }
13 | .#{$fa-css-prefix}-5x { font-size: 5em; }
14 |
--------------------------------------------------------------------------------
/calendar_app/public/font-awesome/scss/_list.scss:
--------------------------------------------------------------------------------
1 | // List Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-ul {
5 | padding-left: 0;
6 | margin-left: $fa-li-width;
7 | list-style-type: none;
8 | > li { position: relative; }
9 | }
10 | .#{$fa-css-prefix}-li {
11 | position: absolute;
12 | left: -$fa-li-width;
13 | width: $fa-li-width;
14 | top: (2em / 14);
15 | text-align: center;
16 | &.#{$fa-css-prefix}-lg {
17 | left: -$fa-li-width + (4em / 14);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/calendar_app/public/font-awesome/scss/_path.scss:
--------------------------------------------------------------------------------
1 | /* FONT PATH
2 | * -------------------------- */
3 |
4 | @font-face {
5 | font-family: 'FontAwesome';
6 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}');
7 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'),
8 | url('#{$fa-font-path}/fontawesome-webfont.woff2?v=#{$fa-version}') format('woff2'),
9 | url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'),
10 | url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'),
11 | url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg');
12 | // src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
13 | font-weight: normal;
14 | font-style: normal;
15 | }
16 |
--------------------------------------------------------------------------------
/calendar_app/public/font-awesome/scss/_rotated-flipped.scss:
--------------------------------------------------------------------------------
1 | // Rotated & Flipped Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); }
5 | .#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); }
6 | .#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); }
7 |
8 | .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); }
9 | .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); }
10 |
11 | // Hook for IE8-9
12 | // -------------------------
13 |
14 | :root .#{$fa-css-prefix}-rotate-90,
15 | :root .#{$fa-css-prefix}-rotate-180,
16 | :root .#{$fa-css-prefix}-rotate-270,
17 | :root .#{$fa-css-prefix}-flip-horizontal,
18 | :root .#{$fa-css-prefix}-flip-vertical {
19 | filter: none;
20 | }
21 |
--------------------------------------------------------------------------------
/calendar_app/public/font-awesome/scss/_screen-reader.scss:
--------------------------------------------------------------------------------
1 | // Screen Readers
2 | // -------------------------
3 |
4 | .sr-only { @include sr-only(); }
5 | .sr-only-focusable { @include sr-only-focusable(); }
6 |
--------------------------------------------------------------------------------
/calendar_app/public/font-awesome/scss/_stacked.scss:
--------------------------------------------------------------------------------
1 | // Stacked Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-stack {
5 | position: relative;
6 | display: inline-block;
7 | width: 2em;
8 | height: 2em;
9 | line-height: 2em;
10 | vertical-align: middle;
11 | }
12 | .#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x {
13 | position: absolute;
14 | left: 0;
15 | width: 100%;
16 | text-align: center;
17 | }
18 | .#{$fa-css-prefix}-stack-1x { line-height: inherit; }
19 | .#{$fa-css-prefix}-stack-2x { font-size: 2em; }
20 | .#{$fa-css-prefix}-inverse { color: $fa-inverse; }
21 |
--------------------------------------------------------------------------------
/calendar_app/public/font-awesome/scss/font-awesome.scss:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
4 | */
5 |
6 | @import "variables";
7 | @import "mixins";
8 | @import "path";
9 | @import "core";
10 | @import "larger";
11 | @import "fixed-width";
12 | @import "list";
13 | @import "bordered-pulled";
14 | @import "animated";
15 | @import "rotated-flipped";
16 | @import "stacked";
17 | @import "icons";
18 | @import "screen-reader";
19 |
--------------------------------------------------------------------------------
/calendar_app/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Project Two: Calendar App
9 |
10 |
12 |
14 |
15 |
16 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/calendar_app/src/app-1/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
20 |
21 |
26 |
27 |
39 |
--------------------------------------------------------------------------------
/calendar_app/src/app-1/components/CalendarEntry.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Day of event: Monday
7 |
8 |
Submit
9 |
10 |
11 |
12 |
13 |
18 |
19 |
61 |
--------------------------------------------------------------------------------
/calendar_app/src/app-2/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
20 |
21 |
26 |
27 |
39 |
--------------------------------------------------------------------------------
/calendar_app/src/app-2/components/CalendarWeek.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
27 |
28 |
36 |
--------------------------------------------------------------------------------
/calendar_app/src/app-2/store.js:
--------------------------------------------------------------------------------
1 | import { seedData } from './seed.js';
2 |
3 | export const store = {
4 | state: {
5 | seedData
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/calendar_app/src/app-3/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
20 |
21 |
26 |
27 |
39 |
--------------------------------------------------------------------------------
/calendar_app/src/app-3/components/CalendarDay.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ day.abbvTitle }}
4 |
5 |
{{ day.id }}
6 |
10 |
11 |
12 |
13 |
14 |
25 |
26 |
58 |
--------------------------------------------------------------------------------
/calendar_app/src/app-3/components/CalendarEvent.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
{{ event.details }}
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
26 |
27 |
55 |
--------------------------------------------------------------------------------
/calendar_app/src/app-3/components/CalendarWeek.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
27 |
28 |
36 |
--------------------------------------------------------------------------------
/calendar_app/src/app-3/store.js:
--------------------------------------------------------------------------------
1 | import { seedData } from './seed.js';
2 |
3 | export const store = {
4 | state: {
5 | seedData
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/calendar_app/src/app-4/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
20 |
21 |
26 |
27 |
39 |
--------------------------------------------------------------------------------
/calendar_app/src/app-4/components/CalendarEvent.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
{{ event.details }}
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
26 |
27 |
55 |
--------------------------------------------------------------------------------
/calendar_app/src/app-4/components/CalendarWeek.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
27 |
28 |
36 |
--------------------------------------------------------------------------------
/calendar_app/src/app-4/store.js:
--------------------------------------------------------------------------------
1 | import { seedData } from './seed.js';
2 |
3 | export const store = {
4 | state: {
5 | seedData
6 | },
7 | getActiveDay () {
8 | return this.state.seedData.find((day) => day.active);
9 | },
10 | setActiveDay (dayId) {
11 | this.state.seedData.map((dayObj) => {
12 | dayObj.id === dayId ? dayObj.active = true : dayObj.active = false;
13 | });
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/calendar_app/src/app-5/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
20 |
21 |
26 |
27 |
39 |
--------------------------------------------------------------------------------
/calendar_app/src/app-5/components/CalendarEvent.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
{{ event.details }}
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
26 |
27 |
55 |
--------------------------------------------------------------------------------
/calendar_app/src/app-5/components/CalendarWeek.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
27 |
28 |
36 |
--------------------------------------------------------------------------------
/calendar_app/src/app-5/store.js:
--------------------------------------------------------------------------------
1 | import { seedData } from './seed.js';
2 |
3 | export const store = {
4 | state: {
5 | seedData
6 | },
7 | getActiveDay () {
8 | return this.state.seedData.find((day) => day.active);
9 | },
10 | setActiveDay (dayId) {
11 | this.state.seedData.map((dayObj) => {
12 | dayObj.id === dayId ? dayObj.active = true : dayObj.active = false;
13 | });
14 | },
15 | submitEvent (eventDetails) {
16 | const activeDay = this.getActiveDay();
17 | activeDay.events.push({ "details": eventDetails, "edit": false });
18 | },
19 | }
20 |
--------------------------------------------------------------------------------
/calendar_app/src/app-6/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
20 |
21 |
26 |
27 |
39 |
--------------------------------------------------------------------------------
/calendar_app/src/app-6/components/CalendarWeek.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
27 |
28 |
36 |
--------------------------------------------------------------------------------
/calendar_app/src/app-6/store.js:
--------------------------------------------------------------------------------
1 | import { seedData } from './seed.js';
2 |
3 | export const store = {
4 | state: {
5 | seedData
6 | },
7 | getActiveDay () {
8 | return this.state.seedData.find((day) => day.active);
9 | },
10 | setActiveDay (dayId) {
11 | this.state.seedData.map((dayObj) => {
12 | dayObj.id === dayId ? dayObj.active = true : dayObj.active = false;
13 | });
14 | },
15 | submitEvent (eventDetails) {
16 | const activeDay = this.getActiveDay();
17 | activeDay.events.push({ "details": eventDetails, "edit": false });
18 | },
19 | editEvent (dayId, eventDetails) {
20 | this.resetEditOfAllEvents();
21 | const dayObj = this.state.seedData.find(
22 | day => day.id === dayId
23 | );
24 | const eventObj = dayObj.events.find(
25 | event => event.details === eventDetails
26 | );
27 | eventObj.edit = true;
28 | },
29 | resetEditOfAllEvents () {
30 | this.state.seedData.map((dayObj) => {
31 | dayObj.events.map((event) => {
32 | event.edit = false;
33 | });
34 | });
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/calendar_app/src/app-7/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
20 |
21 |
26 |
27 |
39 |
--------------------------------------------------------------------------------
/calendar_app/src/app-7/components/CalendarWeek.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
27 |
28 |
36 |
--------------------------------------------------------------------------------
/calendar_app/src/app-complete/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
20 |
21 |
26 |
27 |
39 |
--------------------------------------------------------------------------------
/calendar_app/src/app-complete/components/CalendarWeek.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
27 |
28 |
36 |
--------------------------------------------------------------------------------
/calendar_app/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import App from './app-complete/App.vue';
3 |
4 | new Vue({
5 | render: h => h(App)
6 | }).$mount('#app');
7 |
--------------------------------------------------------------------------------
/custom_events/app-1/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Custom Events
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | Notes
16 |
17 |
18 | Timestamp
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/custom_events/app-1/main.js:
--------------------------------------------------------------------------------
1 | const inputComponent = {
2 | template: ``,
7 | props: ['placeholder'],
8 | data() {
9 | return {
10 | input: ''
11 | }
12 | }
13 | }
14 |
15 | new Vue({
16 | el: '#app',
17 | data: {
18 | notes: [],
19 | timestamps: [],
20 | placeholder: 'Enter a note'
21 | },
22 | components: {
23 | 'input-component': inputComponent
24 | }
25 | })
26 |
--------------------------------------------------------------------------------
/custom_events/app-2/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Custom Events
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
Notes
16 |
17 | {{ note }}
18 |
19 |
20 |
21 |
Timestamp
22 |
23 | {{ timestamp }}
24 |
25 |
26 |
27 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/custom_events/app-2/main.js:
--------------------------------------------------------------------------------
1 | const inputComponent = {
2 | template: ``,
7 | props: ['placeholder'],
8 | data() {
9 | return {
10 | input: ''
11 | };
12 | },
13 | methods: {
14 | monitorEnterKey() {
15 | this.$emit('add-note', {
16 | note: this.input,
17 | timestamp: new Date().toLocaleString()
18 | });
19 | this.input = '';
20 | }
21 | }
22 | };
23 |
24 | new Vue({
25 | el: '#app',
26 | data: {
27 | notes: [],
28 | timestamps: [],
29 | placeholder: 'Enter a note'
30 | },
31 | methods: {
32 | addNote(event) {
33 | this.notes.push(event.note);
34 | this.timestamps.push(event.timestamp);
35 | }
36 | },
37 | components: {
38 | 'input-component': inputComponent
39 | }
40 | });
41 |
--------------------------------------------------------------------------------
/custom_events/app-complete/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Custom Events
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
Notes
16 |
17 | {{ note }}
18 |
19 |
20 |
21 |
Timestamp
22 |
23 | {{ timestamp }}
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/custom_events/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 | Custom Events
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | Notes
18 |
19 |
20 | Timestamp
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/custom_events/app/main.js:
--------------------------------------------------------------------------------
1 | const inputComponent = {
2 | template: ``
3 | }
4 |
5 | new Vue({
6 | el: '#app',
7 | components: {
8 | 'input-component': inputComponent
9 | }
10 | })
11 |
--------------------------------------------------------------------------------
/custom_events/public/styles.css:
--------------------------------------------------------------------------------
1 | html, body {
2 | height: 100%;
3 | }
4 |
5 | #app {
6 | height: inherit;
7 | margin: 0 auto;
8 | display: flex;
9 | flex-direction: column;
10 | align-items: center;
11 | -webkit-align-items: center;
12 | justify-content: center;
13 | -webkit-justify-content: center;
14 | }
15 |
16 | .notes-section {
17 | width: 500px;
18 | }
19 |
20 | .columns {
21 | width: 100%;
22 | }
23 |
24 | .notes, .timestamps {
25 | padding: 5px 0px;
26 | }
27 |
28 | .note-count {
29 | margin-top: 48px;
30 | }
--------------------------------------------------------------------------------
/form_handling/01-basic-button/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 01_Basic_Button
7 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/form_handling/01-basic-button/main.js:
--------------------------------------------------------------------------------
1 | const ButtonRow = {
2 | template: `
3 |
4 |
5 |
6 |
7 |
8 |
`,
9 | methods: {
10 | onHoodieClick(evt) {
11 | console.log('The user clicked button-hoodie', evt);
12 | },
13 | onTeeClick(evt) {
14 | console.log('The user clicked button-tee', evt);
15 | },
16 | onFittedCapClick(evt) {
17 | console.log('The user clicked button-fitted-cap', evt);
18 | },
19 | onJacketClick(evt) {
20 | console.log('The user clicked button-jacket', evt);
21 | }
22 | }
23 | }
24 |
25 | new Vue({
26 | el: '#app',
27 | components: {
28 | 'button-row': ButtonRow
29 | }
30 | })
31 |
--------------------------------------------------------------------------------
/form_handling/02-basic-button/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 02_Basic_Button
7 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/form_handling/02-basic-button/main.js:
--------------------------------------------------------------------------------
1 | const ButtonRow = {
2 | template: `
3 |
4 |
8 |
12 |
16 |
20 |
`,
21 | methods: {
22 | onButtonClick(evt) {
23 | const button = evt.target;
24 | console.log(`The user clicked ${button.name}: ${button.value}`);
25 | }
26 | }
27 | }
28 |
29 | new Vue({
30 | el: '#app',
31 | components: {
32 | 'button-row': ButtonRow
33 | }
34 | })
35 |
--------------------------------------------------------------------------------
/form_handling/03-basic-input/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 03_Basic_Input
7 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/form_handling/03-basic-input/main.js:
--------------------------------------------------------------------------------
1 | const InputForm = {
2 | template: `
3 | `,
11 | methods: {
12 | submitForm(evt) {
13 | evt.preventDefault();
14 | console.log(this.$refs.newItem.value)
15 | }
16 | }
17 | }
18 |
19 | new Vue({
20 | el: '#app',
21 | components: {
22 | 'input-form': InputForm
23 | }
24 | })
25 |
--------------------------------------------------------------------------------
/form_handling/04-data-input/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 04_Data_Input
7 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/form_handling/04-data-input/main.js:
--------------------------------------------------------------------------------
1 | const InputForm = {
2 | template: `
3 | `,
11 | data() {
12 | return {
13 | newItem: ''
14 | }
15 | },
16 | methods: {
17 | submitForm(evt) {
18 | evt.preventDefault();
19 | console.log(this.newItem)
20 | }
21 | }
22 | }
23 |
24 | new Vue({
25 | el: '#app',
26 | components: {
27 | 'input-form': InputForm
28 | }
29 | })
30 |
--------------------------------------------------------------------------------
/form_handling/05-data-input-list/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 05_Data_Input_List
7 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/form_handling/05-data-input-list/main.js:
--------------------------------------------------------------------------------
1 | const InputForm = {
2 | template: `
3 | `,
17 | data() {
18 | return {
19 | newItem: '',
20 | items: []
21 | }
22 | },
23 | methods: {
24 | submitForm(evt) {
25 | this.items.push(this.newItem);
26 | this.newItem = '';
27 | evt.preventDefault();
28 | }
29 | }
30 | }
31 |
32 | new Vue({
33 | el: '#app',
34 | components: {
35 | 'input-form': InputForm
36 | }
37 | })
38 |
--------------------------------------------------------------------------------
/form_handling/06-data-input-multi/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 06_Data_Input_Multi
7 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/form_handling/07-basic-form-validation/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 07_Basic_Form_Validation
7 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/form_handling/08-basic-field-validation/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 08_Basic_Field_Validation
7 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/form_handling/09-remote-persist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 09_Remote_Persist
7 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/form_handling/10-vuex-app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 10_Vuex_App
7 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/form_handling/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Form App
7 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/form_handling/app/main.js:
--------------------------------------------------------------------------------
1 | new Vue({
2 | el: '#app',
3 | })
4 |
--------------------------------------------------------------------------------
/my/upvote/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fullstack-vue-code",
3 | "version": "17.0.0",
4 | "description": "All the code used in the book",
5 | "private": true,
6 | "scripts": {
7 | "install-all": "npm-recursive-install"
8 | },
9 | "author": "Fullstack Vue",
10 | "devDependencies": {
11 | "recursive-install": "1.3.0"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/routing/basics/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 | # local env files
6 | .env.local
7 | .env.*.local
8 |
9 | # Log files
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 | *.suo
18 | *.ntvs*
19 | *.njsproj
20 | *.sln
21 | *.sw*
22 |
--------------------------------------------------------------------------------
/routing/basics/README.md:
--------------------------------------------------------------------------------
1 | # Fullstack Vue
2 |
3 | ## Routing - Basics
4 |
5 | 1. Ensure you have `npm` installed.
6 |
7 | 2. Install the dependencies
8 |
9 | ````
10 | npm install
11 | ````
12 |
13 | 3. Boot the app
14 |
15 | ````
16 | npm run serve
17 | ````
18 |
19 | The server is now running - watch the console output for instructions, but by default, your server is now running (with hot reload) at [http://localhost:8080/](http://localhost:8080/)
--------------------------------------------------------------------------------
/routing/basics/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/routing/basics/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "basics",
3 | "description": "Routing - Basics",
4 | "version": "1.0.0",
5 | "author": "Fullstack.io",
6 | "private": true,
7 | "scripts": {
8 | "serve": "vue-cli-service serve",
9 | "build": "vue-cli-service build",
10 | "lint": "vue-cli-service lint"
11 | },
12 | "dependencies": {
13 | "vue": "^2.5.17",
14 | "vue-router": "^3.0.1"
15 | },
16 | "devDependencies": {
17 | "@vue/cli-plugin-babel": "^3.0.0",
18 | "@vue/cli-plugin-eslint": "^3.0.0",
19 | "@vue/cli-service": "^3.0.0",
20 | "vue-template-compiler": "^2.5.17"
21 | },
22 | "eslintConfig": {
23 | "root": true,
24 | "env": {
25 | "node": true
26 | },
27 | "extends": [
28 | "plugin:vue/essential",
29 | "eslint:recommended"
30 | ],
31 | "rules": {},
32 | "parserOptions": {
33 | "parser": "babel-eslint"
34 | }
35 | },
36 | "postcss": {
37 | "plugins": {
38 | "autoprefixer": {}
39 | }
40 | },
41 | "browserslist": [
42 | "> 1%",
43 | "last 2 versions",
44 | "not ie <= 8"
45 | ]
46 | }
47 |
--------------------------------------------------------------------------------
/routing/basics/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/routing/basics/public/favicon.ico
--------------------------------------------------------------------------------
/routing/basics/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Routing - Basics
9 |
10 |
11 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/routing/basics/public/styles.css:
--------------------------------------------------------------------------------
1 | #app {
2 | font-family: 'Avenir', Helvetica, Arial, sans-serif;
3 | -webkit-font-smoothing: antialiased;
4 | -moz-osx-font-smoothing: grayscale;
5 | text-align: center;
6 | color: #2c3e50;
7 | margin-top: 60px;
8 | }
9 |
10 | h1, h2 {
11 | font-weight: normal;
12 | }
13 |
14 | ul {
15 | list-style-type: none;
16 | padding: 0;
17 | }
18 |
19 | li {
20 | display: inline-block;
21 | margin: 0 10px;
22 | }
23 |
24 | a {
25 | color: #42b983;
26 | }
27 |
28 | .movies a {
29 | padding: 0 10px;
30 | }
31 |
32 | .movies .movies__description {
33 | max-width: 800px;
34 | margin: 0 auto;
35 | }
36 |
--------------------------------------------------------------------------------
/routing/basics/src/app/app.js:
--------------------------------------------------------------------------------
1 | const App = {
2 | name: 'App',
3 | template: ``
16 | };
17 |
18 | export default App;
19 |
--------------------------------------------------------------------------------
/routing/basics/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import App from './app/app-complete';
3 | import { router } from './app/app-complete';
4 |
5 | new Vue({
6 | router,
7 | render: h => h(App),
8 | }).$mount('#app');
9 |
--------------------------------------------------------------------------------
/routing/basics/vue.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | runtimeCompiler: true,
3 | }
4 |
--------------------------------------------------------------------------------
/routing/shopping_cart/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 | # local env files
6 | .env.local
7 | .env.*.local
8 |
9 | # Log files
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 | *.suo
18 | *.ntvs*
19 | *.njsproj
20 | *.sln
21 | *.sw*
22 |
--------------------------------------------------------------------------------
/routing/shopping_cart/README.md:
--------------------------------------------------------------------------------
1 | # Fullstack Vue
2 |
3 | ## Routing - Shopping Cart
4 |
5 | 1. Ensure you have `npm` installed.
6 |
7 | 2. Install the dependencies
8 |
9 | ````
10 | npm install
11 | ````
12 |
13 | 3. Boot the app
14 |
15 | ````
16 | npm run start
17 | ````
18 |
19 | The Node and Webpack servers are now running - watch the console output for instructions. Your entire application is now available at [http://localhost:8080/](http://localhost:8080/)
--------------------------------------------------------------------------------
/routing/shopping_cart/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/routing/shopping_cart/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "shopping_cart",
3 | "description": "Routing - Shopping Cart",
4 | "version": "1.0.0",
5 | "author": "Fullstack.io",
6 | "private": true,
7 | "scripts": {
8 | "start": "concurrently \"npm run server\" \"npm run serve\"",
9 | "server": "node server",
10 | "serve": "vue-cli-service serve",
11 | "build": "vue-cli-service build",
12 | "lint": "vue-cli-service lint"
13 | },
14 | "dependencies": {
15 | "vue": "^2.5.17",
16 | "vue-router": "^3.0.1",
17 | "vuex": "^3.0.1",
18 | "axios": "^0.18.0"
19 | },
20 | "devDependencies": {
21 | "@vue/cli-service": "^3.0.0",
22 | "@vue/cli-plugin-babel": "^3.0.0",
23 | "@vue/cli-plugin-eslint": "^3.0.0",
24 | "vue-template-compiler": "^2.5.17",
25 | "concurrently": "^3.6.1"
26 | },
27 | "eslintConfig": {
28 | "root": true,
29 | "env": {
30 | "node": true
31 | },
32 | "extends": [
33 | "plugin:vue/essential",
34 | "eslint:recommended"
35 | ],
36 | "rules": {},
37 | "parserOptions": {
38 | "parser": "babel-eslint"
39 | }
40 | },
41 | "postcss": {
42 | "plugins": {
43 | "autoprefixer": {}
44 | }
45 | },
46 | "browserslist": [
47 | "> 1%",
48 | "last 2 versions",
49 | "not ie <= 8"
50 | ]
51 | }
52 |
--------------------------------------------------------------------------------
/routing/shopping_cart/public/bulma/bulma.css.map:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/routing/shopping_cart/public/bulma/bulma.css.map
--------------------------------------------------------------------------------
/routing/shopping_cart/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/routing/shopping_cart/public/favicon.ico
--------------------------------------------------------------------------------
/routing/shopping_cart/public/font-awesome/HELP-US-OUT.txt:
--------------------------------------------------------------------------------
1 | I hope you love Font Awesome. If you've found it useful, please do me a favor and check out my latest project,
2 | Fort Awesome (https://fortawesome.com). It makes it easy to put the perfect icons on your website. Choose from our awesome,
3 | comprehensive icon sets or copy and paste your own.
4 |
5 | Please. Check it out.
6 |
7 | -Dave Gandy
8 |
--------------------------------------------------------------------------------
/routing/shopping_cart/public/font-awesome/fonts/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/routing/shopping_cart/public/font-awesome/fonts/FontAwesome.otf
--------------------------------------------------------------------------------
/routing/shopping_cart/public/font-awesome/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/routing/shopping_cart/public/font-awesome/fonts/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/routing/shopping_cart/public/font-awesome/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/routing/shopping_cart/public/font-awesome/fonts/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/routing/shopping_cart/public/font-awesome/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/routing/shopping_cart/public/font-awesome/fonts/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/routing/shopping_cart/public/font-awesome/fonts/fontawesome-webfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/routing/shopping_cart/public/font-awesome/fonts/fontawesome-webfont.woff2
--------------------------------------------------------------------------------
/routing/shopping_cart/public/font-awesome/less/animated.less:
--------------------------------------------------------------------------------
1 | // Animated Icons
2 | // --------------------------
3 |
4 | .@{fa-css-prefix}-spin {
5 | -webkit-animation: fa-spin 2s infinite linear;
6 | animation: fa-spin 2s infinite linear;
7 | }
8 |
9 | .@{fa-css-prefix}-pulse {
10 | -webkit-animation: fa-spin 1s infinite steps(8);
11 | animation: fa-spin 1s infinite steps(8);
12 | }
13 |
14 | @-webkit-keyframes fa-spin {
15 | 0% {
16 | -webkit-transform: rotate(0deg);
17 | transform: rotate(0deg);
18 | }
19 | 100% {
20 | -webkit-transform: rotate(359deg);
21 | transform: rotate(359deg);
22 | }
23 | }
24 |
25 | @keyframes fa-spin {
26 | 0% {
27 | -webkit-transform: rotate(0deg);
28 | transform: rotate(0deg);
29 | }
30 | 100% {
31 | -webkit-transform: rotate(359deg);
32 | transform: rotate(359deg);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/routing/shopping_cart/public/font-awesome/less/bordered-pulled.less:
--------------------------------------------------------------------------------
1 | // Bordered & Pulled
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-border {
5 | padding: .2em .25em .15em;
6 | border: solid .08em @fa-border-color;
7 | border-radius: .1em;
8 | }
9 |
10 | .@{fa-css-prefix}-pull-left { float: left; }
11 | .@{fa-css-prefix}-pull-right { float: right; }
12 |
13 | .@{fa-css-prefix} {
14 | &.@{fa-css-prefix}-pull-left { margin-right: .3em; }
15 | &.@{fa-css-prefix}-pull-right { margin-left: .3em; }
16 | }
17 |
18 | /* Deprecated as of 4.4.0 */
19 | .pull-right { float: right; }
20 | .pull-left { float: left; }
21 |
22 | .@{fa-css-prefix} {
23 | &.pull-left { margin-right: .3em; }
24 | &.pull-right { margin-left: .3em; }
25 | }
26 |
--------------------------------------------------------------------------------
/routing/shopping_cart/public/font-awesome/less/core.less:
--------------------------------------------------------------------------------
1 | // Base Class Definition
2 | // -------------------------
3 |
4 | .@{fa-css-prefix} {
5 | display: inline-block;
6 | font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration
7 | font-size: inherit; // can't have font-size inherit on line above, so need to override
8 | text-rendering: auto; // optimizelegibility throws things off #1094
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/routing/shopping_cart/public/font-awesome/less/fixed-width.less:
--------------------------------------------------------------------------------
1 | // Fixed Width Icons
2 | // -------------------------
3 | .@{fa-css-prefix}-fw {
4 | width: (18em / 14);
5 | text-align: center;
6 | }
7 |
--------------------------------------------------------------------------------
/routing/shopping_cart/public/font-awesome/less/font-awesome.less:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
4 | */
5 |
6 | @import "variables.less";
7 | @import "mixins.less";
8 | @import "path.less";
9 | @import "core.less";
10 | @import "larger.less";
11 | @import "fixed-width.less";
12 | @import "list.less";
13 | @import "bordered-pulled.less";
14 | @import "animated.less";
15 | @import "rotated-flipped.less";
16 | @import "stacked.less";
17 | @import "icons.less";
18 | @import "screen-reader.less";
19 |
--------------------------------------------------------------------------------
/routing/shopping_cart/public/font-awesome/less/larger.less:
--------------------------------------------------------------------------------
1 | // Icon Sizes
2 | // -------------------------
3 |
4 | /* makes the font 33% larger relative to the icon container */
5 | .@{fa-css-prefix}-lg {
6 | font-size: (4em / 3);
7 | line-height: (3em / 4);
8 | vertical-align: -15%;
9 | }
10 | .@{fa-css-prefix}-2x { font-size: 2em; }
11 | .@{fa-css-prefix}-3x { font-size: 3em; }
12 | .@{fa-css-prefix}-4x { font-size: 4em; }
13 | .@{fa-css-prefix}-5x { font-size: 5em; }
14 |
--------------------------------------------------------------------------------
/routing/shopping_cart/public/font-awesome/less/list.less:
--------------------------------------------------------------------------------
1 | // List Icons
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-ul {
5 | padding-left: 0;
6 | margin-left: @fa-li-width;
7 | list-style-type: none;
8 | > li { position: relative; }
9 | }
10 | .@{fa-css-prefix}-li {
11 | position: absolute;
12 | left: -@fa-li-width;
13 | width: @fa-li-width;
14 | top: (2em / 14);
15 | text-align: center;
16 | &.@{fa-css-prefix}-lg {
17 | left: (-@fa-li-width + (4em / 14));
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/routing/shopping_cart/public/font-awesome/less/path.less:
--------------------------------------------------------------------------------
1 | /* FONT PATH
2 | * -------------------------- */
3 |
4 | @font-face {
5 | font-family: 'FontAwesome';
6 | src: url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}');
7 | src: url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype'),
8 | url('@{fa-font-path}/fontawesome-webfont.woff2?v=@{fa-version}') format('woff2'),
9 | url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff'),
10 | url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype'),
11 | url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg');
12 | // src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
13 | font-weight: normal;
14 | font-style: normal;
15 | }
16 |
--------------------------------------------------------------------------------
/routing/shopping_cart/public/font-awesome/less/rotated-flipped.less:
--------------------------------------------------------------------------------
1 | // Rotated & Flipped Icons
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); }
5 | .@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); }
6 | .@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); }
7 |
8 | .@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); }
9 | .@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); }
10 |
11 | // Hook for IE8-9
12 | // -------------------------
13 |
14 | :root .@{fa-css-prefix}-rotate-90,
15 | :root .@{fa-css-prefix}-rotate-180,
16 | :root .@{fa-css-prefix}-rotate-270,
17 | :root .@{fa-css-prefix}-flip-horizontal,
18 | :root .@{fa-css-prefix}-flip-vertical {
19 | filter: none;
20 | }
21 |
--------------------------------------------------------------------------------
/routing/shopping_cart/public/font-awesome/less/screen-reader.less:
--------------------------------------------------------------------------------
1 | // Screen Readers
2 | // -------------------------
3 |
4 | .sr-only { .sr-only(); }
5 | .sr-only-focusable { .sr-only-focusable(); }
6 |
--------------------------------------------------------------------------------
/routing/shopping_cart/public/font-awesome/less/stacked.less:
--------------------------------------------------------------------------------
1 | // Stacked Icons
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-stack {
5 | position: relative;
6 | display: inline-block;
7 | width: 2em;
8 | height: 2em;
9 | line-height: 2em;
10 | vertical-align: middle;
11 | }
12 | .@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x {
13 | position: absolute;
14 | left: 0;
15 | width: 100%;
16 | text-align: center;
17 | }
18 | .@{fa-css-prefix}-stack-1x { line-height: inherit; }
19 | .@{fa-css-prefix}-stack-2x { font-size: 2em; }
20 | .@{fa-css-prefix}-inverse { color: @fa-inverse; }
21 |
--------------------------------------------------------------------------------
/routing/shopping_cart/public/font-awesome/scss/_animated.scss:
--------------------------------------------------------------------------------
1 | // Spinning Icons
2 | // --------------------------
3 |
4 | .#{$fa-css-prefix}-spin {
5 | -webkit-animation: fa-spin 2s infinite linear;
6 | animation: fa-spin 2s infinite linear;
7 | }
8 |
9 | .#{$fa-css-prefix}-pulse {
10 | -webkit-animation: fa-spin 1s infinite steps(8);
11 | animation: fa-spin 1s infinite steps(8);
12 | }
13 |
14 | @-webkit-keyframes fa-spin {
15 | 0% {
16 | -webkit-transform: rotate(0deg);
17 | transform: rotate(0deg);
18 | }
19 | 100% {
20 | -webkit-transform: rotate(359deg);
21 | transform: rotate(359deg);
22 | }
23 | }
24 |
25 | @keyframes fa-spin {
26 | 0% {
27 | -webkit-transform: rotate(0deg);
28 | transform: rotate(0deg);
29 | }
30 | 100% {
31 | -webkit-transform: rotate(359deg);
32 | transform: rotate(359deg);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/routing/shopping_cart/public/font-awesome/scss/_bordered-pulled.scss:
--------------------------------------------------------------------------------
1 | // Bordered & Pulled
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-border {
5 | padding: .2em .25em .15em;
6 | border: solid .08em $fa-border-color;
7 | border-radius: .1em;
8 | }
9 |
10 | .#{$fa-css-prefix}-pull-left { float: left; }
11 | .#{$fa-css-prefix}-pull-right { float: right; }
12 |
13 | .#{$fa-css-prefix} {
14 | &.#{$fa-css-prefix}-pull-left { margin-right: .3em; }
15 | &.#{$fa-css-prefix}-pull-right { margin-left: .3em; }
16 | }
17 |
18 | /* Deprecated as of 4.4.0 */
19 | .pull-right { float: right; }
20 | .pull-left { float: left; }
21 |
22 | .#{$fa-css-prefix} {
23 | &.pull-left { margin-right: .3em; }
24 | &.pull-right { margin-left: .3em; }
25 | }
26 |
--------------------------------------------------------------------------------
/routing/shopping_cart/public/font-awesome/scss/_core.scss:
--------------------------------------------------------------------------------
1 | // Base Class Definition
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix} {
5 | display: inline-block;
6 | font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration
7 | font-size: inherit; // can't have font-size inherit on line above, so need to override
8 | text-rendering: auto; // optimizelegibility throws things off #1094
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/routing/shopping_cart/public/font-awesome/scss/_fixed-width.scss:
--------------------------------------------------------------------------------
1 | // Fixed Width Icons
2 | // -------------------------
3 | .#{$fa-css-prefix}-fw {
4 | width: (18em / 14);
5 | text-align: center;
6 | }
7 |
--------------------------------------------------------------------------------
/routing/shopping_cart/public/font-awesome/scss/_larger.scss:
--------------------------------------------------------------------------------
1 | // Icon Sizes
2 | // -------------------------
3 |
4 | /* makes the font 33% larger relative to the icon container */
5 | .#{$fa-css-prefix}-lg {
6 | font-size: (4em / 3);
7 | line-height: (3em / 4);
8 | vertical-align: -15%;
9 | }
10 | .#{$fa-css-prefix}-2x { font-size: 2em; }
11 | .#{$fa-css-prefix}-3x { font-size: 3em; }
12 | .#{$fa-css-prefix}-4x { font-size: 4em; }
13 | .#{$fa-css-prefix}-5x { font-size: 5em; }
14 |
--------------------------------------------------------------------------------
/routing/shopping_cart/public/font-awesome/scss/_list.scss:
--------------------------------------------------------------------------------
1 | // List Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-ul {
5 | padding-left: 0;
6 | margin-left: $fa-li-width;
7 | list-style-type: none;
8 | > li { position: relative; }
9 | }
10 | .#{$fa-css-prefix}-li {
11 | position: absolute;
12 | left: -$fa-li-width;
13 | width: $fa-li-width;
14 | top: (2em / 14);
15 | text-align: center;
16 | &.#{$fa-css-prefix}-lg {
17 | left: -$fa-li-width + (4em / 14);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/routing/shopping_cart/public/font-awesome/scss/_path.scss:
--------------------------------------------------------------------------------
1 | /* FONT PATH
2 | * -------------------------- */
3 |
4 | @font-face {
5 | font-family: 'FontAwesome';
6 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}');
7 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'),
8 | url('#{$fa-font-path}/fontawesome-webfont.woff2?v=#{$fa-version}') format('woff2'),
9 | url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'),
10 | url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'),
11 | url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg');
12 | // src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
13 | font-weight: normal;
14 | font-style: normal;
15 | }
16 |
--------------------------------------------------------------------------------
/routing/shopping_cart/public/font-awesome/scss/_rotated-flipped.scss:
--------------------------------------------------------------------------------
1 | // Rotated & Flipped Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); }
5 | .#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); }
6 | .#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); }
7 |
8 | .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); }
9 | .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); }
10 |
11 | // Hook for IE8-9
12 | // -------------------------
13 |
14 | :root .#{$fa-css-prefix}-rotate-90,
15 | :root .#{$fa-css-prefix}-rotate-180,
16 | :root .#{$fa-css-prefix}-rotate-270,
17 | :root .#{$fa-css-prefix}-flip-horizontal,
18 | :root .#{$fa-css-prefix}-flip-vertical {
19 | filter: none;
20 | }
21 |
--------------------------------------------------------------------------------
/routing/shopping_cart/public/font-awesome/scss/_screen-reader.scss:
--------------------------------------------------------------------------------
1 | // Screen Readers
2 | // -------------------------
3 |
4 | .sr-only { @include sr-only(); }
5 | .sr-only-focusable { @include sr-only-focusable(); }
6 |
--------------------------------------------------------------------------------
/routing/shopping_cart/public/font-awesome/scss/_stacked.scss:
--------------------------------------------------------------------------------
1 | // Stacked Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-stack {
5 | position: relative;
6 | display: inline-block;
7 | width: 2em;
8 | height: 2em;
9 | line-height: 2em;
10 | vertical-align: middle;
11 | }
12 | .#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x {
13 | position: absolute;
14 | left: 0;
15 | width: 100%;
16 | text-align: center;
17 | }
18 | .#{$fa-css-prefix}-stack-1x { line-height: inherit; }
19 | .#{$fa-css-prefix}-stack-2x { font-size: 2em; }
20 | .#{$fa-css-prefix}-inverse { color: $fa-inverse; }
21 |
--------------------------------------------------------------------------------
/routing/shopping_cart/public/font-awesome/scss/font-awesome.scss:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
4 | */
5 |
6 | @import "variables";
7 | @import "mixins";
8 | @import "path";
9 | @import "core";
10 | @import "larger";
11 | @import "fixed-width";
12 | @import "list";
13 | @import "bordered-pulled";
14 | @import "animated";
15 | @import "rotated-flipped";
16 | @import "stacked";
17 | @import "icons";
18 | @import "screen-reader";
19 |
--------------------------------------------------------------------------------
/routing/shopping_cart/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Routing - Shopping Cart
9 |
10 |
11 |
12 |
13 |
14 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/routing/shopping_cart/server-cart-data.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": 1,
4 | "title": "Fullstack Hoodie",
5 | "description": "Lightweight, breathable hoodie with the Fullstack Crest. Guaranteed to keep you looking fresh while warm.",
6 | "price": 19.99,
7 | "image_tag": "hoodie.png",
8 | "quantity": 1
9 | }
10 | ]
--------------------------------------------------------------------------------
/routing/shopping_cart/server-product-data.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": 1,
4 | "title": "Fullstack Hoodie",
5 | "description": "Lightweight, breathable hoodie with the Fullstack Crest. Guaranteed to keep you looking fresh while warm.",
6 | "product_type": "hoodies/jackets",
7 | "image_tag": "hoodie.png",
8 | "created_at": 2017,
9 | "price": 19.99
10 | },
11 | {
12 | "id": 2,
13 | "title": "Fullstack Tee",
14 | "description": "The original Fullstack clothing item. Always prepared to keep your style in check.",
15 | "product_type": "shirts/t-shirts",
16 | "image_tag": "tee.png",
17 | "created_at": 2017,
18 | "price": 15.99
19 | },
20 | {
21 | "id": 3,
22 | "title": "Fullstack Fitted Cap",
23 | "description": "Stay comfortable and cool with the first Fullstack Fitted Cap, featuring a normal bill and medium crown.",
24 | "product_type": "caps/hats",
25 | "image_tag": "cap.png",
26 | "created_at": 2018,
27 | "price": 15.99
28 | },
29 | {
30 | "id": 4,
31 | "title": "Fullstack Jacket",
32 | "description": "Keep warm and protected with the rugged, durable Fullstack lightweight jacket.",
33 | "product_type": "hoodies/jackets",
34 | "image_tag": "jacket.png",
35 | "created_at": 2018,
36 | "price": 49.99
37 | }
38 | ]
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-1/assets/cap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/routing/shopping_cart/src/app-1/assets/cap.png
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-1/assets/hoodie.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/routing/shopping_cart/src/app-1/assets/hoodie.png
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-1/assets/jacket.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/routing/shopping_cart/src/app-1/assets/jacket.png
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-1/assets/tee.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/routing/shopping_cart/src/app-1/assets/tee.png
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-1/components/NotFound.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Sorry. Page Not Found :(
4 |
Use the navigation links above to navigate between the product and
5 | cart screens.
6 |
7 |
8 |
9 |
14 |
15 |
17 |
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-1/components/product/ProductList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
12 |
13 | # of products: 4
14 |
15 |
16 |
17 |
18 |
34 |
35 |
53 |
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-1/components/product/ProductListItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ productItem.title }}
4 |
7 | Add to Cart
8 |
9 |
10 |
{{ productItem.description }}
11 |
12 | {{ productItem.price }}
13 |
14 |
15 |
16 |
17 |
30 |
31 |
36 |
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-1/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import VueRouter from 'vue-router';
3 | import CartList from '../components/cart/CartList.vue';
4 | import ProductList from '../components/product/ProductList.vue';
5 | import NotFound from '../components/NotFound.vue';
6 |
7 | Vue.use(VueRouter);
8 |
9 | const router = new VueRouter({
10 | mode: 'history',
11 | routes: [
12 | {
13 | path: '/products',
14 | component: ProductList
15 | },
16 | {
17 | path: '/cart',
18 | component: CartList
19 | },
20 | {
21 | path: '/',
22 | redirect: '/products'
23 | },
24 | {
25 | path: '*',
26 | component: NotFound
27 | }
28 | ]
29 | });
30 |
31 | export default router;
32 |
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-1/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import Vuex from 'vuex';
3 | import product from './modules/product';
4 | import cart from './modules/cart';
5 |
6 | Vue.use(Vuex);
7 |
8 | export default new Vuex.Store({
9 | modules: {
10 | product,
11 | cart
12 | }
13 | });
14 |
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-1/store/modules/product/index.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | const state = {
4 | productItems: []
5 | }
6 |
7 | const mutations = {
8 | UPDATE_PRODUCT_ITEMS (state, payload) {
9 | state.productItems = payload;
10 | }
11 | }
12 |
13 | const actions = {
14 | getProductItems ({ commit }) {
15 | axios.get('/api/products?token=D6W69PRgCoDKgHZGJmRUNA').then((response) => {
16 | commit('UPDATE_PRODUCT_ITEMS', response.data)
17 | });
18 | }
19 | }
20 |
21 | const getters = {
22 | productItems: state => state.productItems
23 | }
24 |
25 | const productModule = {
26 | state,
27 | mutations,
28 | actions,
29 | getters
30 | }
31 |
32 | export default productModule;
33 |
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-2/assets/cap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/routing/shopping_cart/src/app-2/assets/cap.png
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-2/assets/hoodie.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/routing/shopping_cart/src/app-2/assets/hoodie.png
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-2/assets/jacket.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/routing/shopping_cart/src/app-2/assets/jacket.png
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-2/assets/tee.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/routing/shopping_cart/src/app-2/assets/tee.png
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-2/components/NotFound.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Sorry. Page Not Found :(
4 |
Use the navigation links above to navigate between the product and
5 | cart screens.
6 |
7 |
8 |
9 |
14 |
15 |
17 |
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-2/components/product/ProductList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
12 |
13 | # of products: 4
14 |
15 |
16 |
17 |
18 |
34 |
35 |
53 |
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-2/components/product/ProductListItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 | {{ productItem.title }}
7 |
8 |
11 | Add to Cart
12 |
13 |
14 |
{{ productItem.description }}
15 |
16 | {{ productItem.price }}
17 |
18 |
19 |
20 |
21 |
32 |
33 |
38 |
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-2/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import VueRouter from 'vue-router';
3 | import CartList from '../components/cart/CartList.vue';
4 | import ProductList from '../components/product/ProductList.vue';
5 | import ProductItem from '../components/product/ProductItem.vue';
6 | import NotFound from '../components/NotFound.vue';
7 |
8 | Vue.use(VueRouter);
9 |
10 | const router = new VueRouter({
11 | mode: 'history',
12 | routes: [
13 | {
14 | path: '/products',
15 | component: ProductList
16 | },
17 | {
18 | path: '/products/:id',
19 | component: ProductItem,
20 | props: true
21 | },
22 | {
23 | path: '/cart',
24 | component: CartList
25 | },
26 | {
27 | path: '/',
28 | redirect: '/products'
29 | },
30 | {
31 | path: '*',
32 | component: NotFound
33 | }
34 | ]
35 | });
36 |
37 | export default router;
38 |
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-2/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import Vuex from 'vuex';
3 | import product from './modules/product';
4 | import cart from './modules/cart';
5 |
6 | Vue.use(Vuex);
7 |
8 | export default new Vuex.Store({
9 | modules: {
10 | product,
11 | cart
12 | }
13 | });
14 |
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-2/store/modules/product/index.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | const state = {
4 | productItems: []
5 | }
6 |
7 | const mutations = {
8 | UPDATE_PRODUCT_ITEMS (state, payload) {
9 | state.productItems = payload;
10 | }
11 | }
12 |
13 | const actions = {
14 | getProductItems ({ commit }) {
15 | axios.get('/api/products?token=D6W69PRgCoDKgHZGJmRUNA').then((response) => {
16 | commit('UPDATE_PRODUCT_ITEMS', response.data)
17 | });
18 | }
19 | }
20 |
21 | const getters = {
22 | productItems: state => state.productItems,
23 | productItemFromId: (state) => (id) => {
24 | return state.productItems.find(productItem => productItem.id === id)
25 | }
26 | }
27 |
28 | const productModule = {
29 | state,
30 | mutations,
31 | actions,
32 | getters
33 | }
34 |
35 | export default productModule;
36 |
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-3/assets/cap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/routing/shopping_cart/src/app-3/assets/cap.png
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-3/assets/hoodie.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/routing/shopping_cart/src/app-3/assets/hoodie.png
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-3/assets/jacket.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/routing/shopping_cart/src/app-3/assets/jacket.png
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-3/assets/tee.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/routing/shopping_cart/src/app-3/assets/tee.png
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-3/components/NotFound.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Sorry. Page Not Found :(
4 |
Use the navigation links above to navigate between the product and
5 | cart screens.
6 |
7 |
8 |
9 |
14 |
15 |
17 |
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-3/components/login/LoginBox.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Fullstack Clothing
4 |
8 |
9 |
10 |
11 |
30 |
31 |
36 |
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-3/components/product/ProductList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
12 |
13 | # of products: 4
14 |
15 |
16 |
17 |
18 |
34 |
35 |
53 |
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-3/components/product/ProductListItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 | {{ productItem.title }}
7 |
8 |
11 | Add to Cart
12 |
13 |
14 |
{{ productItem.description }}
15 |
16 | {{ productItem.price }}
17 |
18 |
19 |
20 |
21 |
32 |
33 |
38 |
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-3/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import VueRouter from 'vue-router';
3 | import CartList from '../components/cart/CartList.vue';
4 | import ProductList from '../components/product/ProductList.vue';
5 | import ProductItem from '../components/product/ProductItem.vue';
6 | import LoginBox from '../components/login/LoginBox.vue';
7 | import NotFound from '../components/NotFound.vue';
8 |
9 | Vue.use(VueRouter);
10 |
11 | const router = new VueRouter({
12 | mode: 'history',
13 | routes: [
14 | {
15 | path: '/products',
16 | component: ProductList
17 | },
18 | {
19 | path: '/products/:id',
20 | component: ProductItem,
21 | props: true
22 | },
23 | {
24 | path: '/cart',
25 | component: CartList
26 | },
27 | {
28 | path: '/login',
29 | component: LoginBox
30 | },
31 | {
32 | path: '/',
33 | redirect: '/products'
34 | },
35 | {
36 | path: '*',
37 | component: NotFound
38 | }
39 | ]
40 | });
41 |
42 | export default router;
43 |
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-3/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import Vuex from 'vuex';
3 | import product from './modules/product';
4 | import cart from './modules/cart';
5 | import login from './modules/login';
6 |
7 | Vue.use(Vuex);
8 |
9 | export default new Vuex.Store({
10 | modules: {
11 | product,
12 | cart,
13 | login
14 | }
15 | });
16 |
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-3/store/modules/login/index.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | const state = {
4 | token: null,
5 | loading: false
6 | }
7 |
8 | const mutations = {
9 | SET_TOKEN (state, token) {
10 | state.token = token;
11 | },
12 | LOGIN_PENDING (state) {
13 | state.loading = true;
14 | },
15 | LOGIN_SUCCESS (state) {
16 | state.loading = false;
17 | }
18 | }
19 |
20 | const actions = {
21 | login ({ commit }) {
22 | commit('LOGIN_PENDING'); // login pending
23 | return axios.post('/api/login').then((response) => {
24 | localStorage.setItem("token", response.data.token);
25 | commit('SET_TOKEN', response.data.token);
26 | commit('LOGIN_SUCCESS'); // login success
27 | });
28 | },
29 | logout ({ commit }) {
30 | return new Promise((resolve) => {
31 | localStorage.removeItem("token");
32 | commit('SET_TOKEN', null);
33 | resolve();
34 | });
35 | }
36 | }
37 |
38 | const getters = {
39 | token: state => state.token,
40 | loading: state => state.loading
41 | }
42 |
43 | const loginModule = {
44 | state,
45 | mutations,
46 | actions,
47 | getters
48 | }
49 |
50 | export default loginModule;
51 |
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-3/store/modules/product/index.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | const state = {
4 | productItems: []
5 | }
6 |
7 | const mutations = {
8 | UPDATE_PRODUCT_ITEMS (state, payload) {
9 | state.productItems = payload;
10 | }
11 | }
12 |
13 | const actions = {
14 | getProductItems ({ commit }, token) {
15 | axios.get(`/api/products?token=${token}`).then((response) => {
16 | commit('UPDATE_PRODUCT_ITEMS', response.data)
17 | });
18 | }
19 | }
20 |
21 | const getters = {
22 | productItems: state => state.productItems,
23 | productItemFromId: (state) => (id) => {
24 | return state.productItems.find(productItem => productItem.id === id)
25 | }
26 | }
27 |
28 | const productModule = {
29 | state,
30 | mutations,
31 | actions,
32 | getters
33 | }
34 |
35 | export default productModule;
36 |
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-complete/assets/cap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/routing/shopping_cart/src/app-complete/assets/cap.png
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-complete/assets/hoodie.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/routing/shopping_cart/src/app-complete/assets/hoodie.png
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-complete/assets/jacket.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/routing/shopping_cart/src/app-complete/assets/jacket.png
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-complete/assets/tee.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/routing/shopping_cart/src/app-complete/assets/tee.png
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-complete/components/NotFound.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Sorry. Page Not Found :(
4 |
Use the navigation links above to navigate between the product and
5 | cart screens.
6 |
7 |
8 |
9 |
14 |
15 |
17 |
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-complete/components/login/LoginBox.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Fullstack Clothing
4 |
8 |
9 |
10 |
11 |
30 |
31 |
36 |
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-complete/components/product/ProductList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
12 |
13 | # of products: 4
14 |
15 |
16 |
17 |
18 |
34 |
35 |
53 |
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-complete/components/product/ProductListItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 | {{ productItem.title }}
7 |
8 |
11 | Add to Cart
12 |
13 |
14 |
{{ productItem.description }}
15 |
16 | {{ productItem.price }}
17 |
18 |
19 |
20 |
21 |
32 |
33 |
38 |
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-complete/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import Vuex from 'vuex';
3 | import product from './modules/product';
4 | import cart from './modules/cart';
5 | import login from './modules/login';
6 |
7 | Vue.use(Vuex);
8 |
9 | export default new Vuex.Store({
10 | modules: {
11 | product,
12 | cart,
13 | login
14 | }
15 | });
16 |
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-complete/store/modules/login/index.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | const state = {
4 | token: null,
5 | loading: false
6 | }
7 |
8 | const mutations = {
9 | SET_TOKEN (state, token) {
10 | state.token = token;
11 | },
12 | LOGIN_PENDING (state) {
13 | state.loading = true;
14 | },
15 | LOGIN_SUCCESS (state) {
16 | state.loading = false;
17 | }
18 | }
19 |
20 | const actions = {
21 | login ({ commit }) {
22 | commit('LOGIN_PENDING');
23 | return axios.post('/api/login').then((response) => {
24 | localStorage.setItem("token", response.data.token);
25 | commit('SET_TOKEN', response.data.token);
26 | commit('LOGIN_SUCCESS');
27 | });
28 | },
29 | logout ({ commit }) {
30 | return new Promise((resolve) => {
31 | localStorage.removeItem("token");
32 | commit('SET_TOKEN', null);
33 | resolve();
34 | });
35 | }
36 | }
37 |
38 | const getters = {
39 | token: state => state.token,
40 | loading: state => state.loading
41 | }
42 |
43 | const loginModule = {
44 | state,
45 | mutations,
46 | actions,
47 | getters
48 | }
49 |
50 | export default loginModule;
51 |
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app-complete/store/modules/product/index.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | const state = {
4 | productItems: []
5 | }
6 |
7 | const mutations = {
8 | UPDATE_PRODUCT_ITEMS (state, payload) {
9 | state.productItems = payload;
10 | }
11 | }
12 |
13 | const actions = {
14 | getProductItems ({ commit }, token) {
15 | axios.get(`/api/products?token=${token}`).then((response) => {
16 | commit('UPDATE_PRODUCT_ITEMS', response.data)
17 | });
18 | }
19 | }
20 |
21 | const getters = {
22 | productItems: state => state.productItems,
23 | productItemFromId: (state) => (id) => {
24 | return state.productItems.find(productItem => productItem.id === id)
25 | }
26 | }
27 |
28 | const productModule = {
29 | state,
30 | mutations,
31 | actions,
32 | getters
33 | }
34 |
35 | export default productModule;
36 |
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
16 |
28 |
29 |
65 |
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app/assets/cap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/routing/shopping_cart/src/app/assets/cap.png
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app/assets/hoodie.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/routing/shopping_cart/src/app/assets/hoodie.png
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app/assets/jacket.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/routing/shopping_cart/src/app/assets/jacket.png
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app/assets/tee.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/routing/shopping_cart/src/app/assets/tee.png
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app/components/product/ProductList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
12 |
13 | # of products: 4
14 |
15 |
16 |
17 |
18 |
37 |
38 |
56 |
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app/components/product/ProductListItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ productItem.title }}
4 |
7 | Add to Cart
8 |
9 |
10 |
{{ productItem.description }}
11 |
12 | {{ productItem.price }}
13 |
14 |
15 |
16 |
17 |
30 |
31 |
36 |
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import Vuex from 'vuex';
3 | import product from './modules/product';
4 | import cart from './modules/cart';
5 |
6 | Vue.use(Vuex);
7 |
8 | export default new Vuex.Store({
9 | modules: {
10 | product,
11 | cart
12 | }
13 | })
14 |
--------------------------------------------------------------------------------
/routing/shopping_cart/src/app/store/modules/product/index.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | const state = {
4 | productItems: []
5 | }
6 |
7 | const mutations = {
8 | UPDATE_PRODUCT_ITEMS (state, payload) {
9 | state.productItems = payload;
10 | }
11 | }
12 |
13 | const actions = {
14 | getProductItems ({ commit }) {
15 | axios.get('/api/products?token=D6W69PRgCoDKgHZGJmRUNA').then((response) => {
16 | commit('UPDATE_PRODUCT_ITEMS', response.data)
17 | });
18 | }
19 | }
20 |
21 | const getters = {
22 | productItems: state => state.productItems
23 | }
24 |
25 | const productModule = {
26 | state,
27 | mutations,
28 | actions,
29 | getters
30 | }
31 |
32 | export default productModule;
33 |
--------------------------------------------------------------------------------
/routing/shopping_cart/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import App from './app-complete/App.vue';
3 | import router from './app-complete/router';
4 | import store from './app-complete/store';
5 |
6 | new Vue({
7 | router,
8 | store,
9 | render: h => h(App)
10 | }).$mount('#app');
11 |
--------------------------------------------------------------------------------
/routing/shopping_cart/vue.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | devServer: {
3 | proxy: {
4 | '/api': {
5 | target: 'http://localhost:3000/',
6 | changeOrigin: true,
7 | pathRewrite: {
8 | '^/api': ''
9 | }
10 | }
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/testing/basics/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 | # local env files
6 | .env.local
7 | .env.*.local
8 |
9 | # Log files
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 | *.suo
18 | *.ntvs*
19 | *.njsproj
20 | *.sln
21 | *.sw*
22 |
--------------------------------------------------------------------------------
/testing/basics/README.md:
--------------------------------------------------------------------------------
1 | # Fullstack Vue
2 |
3 | ## Testing - Basics
4 |
5 | 1. Ensure you have `npm` installed.
6 |
7 | 2. Install the dependencies
8 |
9 | ````
10 | npm install
11 | ````
12 |
13 | 3. Boot the app
14 |
15 | ````
16 | npm run serve
17 | ````
18 |
19 | The server is now running - watch the console output for instructions, but by default, your server is now running (with hot reload) at [http://localhost:8080/](http://localhost:8080/)
20 |
21 | 4. Run unit tests of working file
22 |
23 | ````
24 | npm run test
25 | ````
26 |
27 | 5. Run unit tests of working file, in watch mode
28 |
29 | ````
30 | npm run test:watch
31 | ````
32 |
33 | 6. Run all unit tests
34 |
35 | ````
36 | npm run test:unit
37 | ````
--------------------------------------------------------------------------------
/testing/basics/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/testing/basics/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/testing/basics/public/favicon.ico
--------------------------------------------------------------------------------
/testing/basics/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Testing - Basics
9 |
10 |
11 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/testing/basics/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import App from './App.vue';
3 |
4 | new Vue({
5 | render: h => h(App)
6 | }).$mount('#app');
7 |
--------------------------------------------------------------------------------
/testing/basics/tests/unit/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | mocha: true
4 | }
5 | }
--------------------------------------------------------------------------------
/testing/basics/tests/unit/App.1.spec.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import App from '@/App';
3 | import { expect } from 'chai';
4 |
5 | describe('App.vue', () => {
6 | it('should render correct contents', () => {
7 | const Constructor = Vue.extend(App);
8 | const vm = new Constructor().$mount();
9 |
10 | expect(
11 | vm.$el.querySelector('.ui.selectable thead tr th').textContent
12 | ).to.contain('Items');
13 | expect(
14 | vm.$el.querySelector('.ui.button').textContent
15 | ).to.contain('Add');
16 | expect(
17 | vm.$el.querySelector('.ui.label').textContent
18 | ).to.contain('Remove all');
19 | });
20 |
21 | it('should set correct default data', () => {
22 | const initialData = App.data();
23 |
24 | expect(initialData.item).to.equal('');
25 | expect(initialData.items).to.deep.equal([]);
26 | });
27 | });
28 |
--------------------------------------------------------------------------------
/testing/basics/tests/unit/App.2.spec.js:
--------------------------------------------------------------------------------
1 | import App from '@/App';
2 | import {shallowMount} from '@vue/test-utils';
3 | import { expect } from 'chai';
4 |
5 | describe('App.vue', () => {
6 | let wrapper;
7 |
8 | beforeEach(() => {
9 | wrapper = shallowMount(App);
10 | });
11 |
12 | it('should render correct contents', () => {
13 | expect(wrapper.html()).to.contain('Items | ');
14 | expect(wrapper.html()).to.contain(
15 | ''
16 | );
17 | expect(wrapper.html()).to.contain(
18 | ''
19 | );
20 | expect(wrapper.html()).to.contain(
21 | 'Remove all'
22 | );
23 | });
24 |
25 | it('should set correct default data', () => {
26 | expect(wrapper.vm.item).to.equal('');
27 | expect(wrapper.vm.items).to.deep.equal([]);
28 | });
29 |
30 | it('should have the "Add" button disabled', () => {
31 | const addItemButton = wrapper.find('.ui.button');
32 |
33 | expect(addItemButton.element.disabled).to.be.true;
34 | });
35 | });
36 |
--------------------------------------------------------------------------------
/testing/basics/tests/unit/App.spec.js:
--------------------------------------------------------------------------------
1 | import { expect } from 'chai';
2 |
3 | describe('App.vue', () => {
4 | it('should run this dummy test', () => {
5 | expect('Dummy' + ' Test!').to.equal('Dummy Test!');
6 | });
7 | });
8 |
--------------------------------------------------------------------------------
/testing/weather/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 | # local env files
6 | .env.local
7 | .env.*.local
8 |
9 | # Log files
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 | *.suo
18 | *.ntvs*
19 | *.njsproj
20 | *.sln
21 | *.sw*
22 |
--------------------------------------------------------------------------------
/testing/weather/README.md:
--------------------------------------------------------------------------------
1 | # Fullstack Vue
2 |
3 | ## Testing - Weather
4 |
5 | 1. Ensure you have `npm` installed.
6 |
7 | 2. Install the dependencies
8 |
9 | ````
10 | npm install
11 | ````
12 |
13 | 3. Boot the app
14 |
15 | ````
16 | npm run start
17 | ````
18 |
19 | The Node and Webpack servers are now running - watch the console output for instructions. Your entire application is now available at [http://localhost:8080/](http://localhost:8080/)
20 |
21 | 4. Run unit tests of working file
22 |
23 | ````
24 | npm run test
25 | ````
26 |
27 | 5. Run unit tests of working file, in watch mode
28 |
29 | ````
30 | npm run test:watch
31 | ````
32 |
33 | 6. Run all unit tests
34 |
35 | ````
36 | npm run test:unit
37 | ````
--------------------------------------------------------------------------------
/testing/weather/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/testing/weather/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/testing/weather/public/favicon.ico
--------------------------------------------------------------------------------
/testing/weather/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Testing - Weather
9 |
10 |
11 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/testing/weather/server.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-param-reassign */
2 | const express = require("express");
3 | const bodyParser = require("body-parser");
4 | const axios = require("axios");
5 |
6 | const app = express();
7 |
8 | app.set("port", process.env.PORT || 3000);
9 |
10 | app.use(bodyParser.json());
11 | app.use(bodyParser.urlencoded({ extended: true }));
12 |
13 | app.use((req, res, next) => {
14 | res.setHeader(
15 | "Cache-Control",
16 | "no-cache, no-store, must-revalidate"
17 | );
18 | res.setHeader("Pragma", "no-cache");
19 | res.setHeader("Expires", "0");
20 | next();
21 | });
22 |
23 | app.get("/weather", (req, res) => {
24 | const id = Number(req.query.id);
25 | axios.get(`https://www.metaweather.com/api/location/${id}/`)
26 | .then(response => {
27 | res.setHeader("Cache-Control", "no-cache");
28 | res.json(response.data);
29 | })
30 | .catch(error => {
31 | console.log(error); // eslint-disable-line no-console
32 | });
33 | });
34 |
35 | app.listen(app.get("port"), () => {
36 | console.log( // eslint-disable-line no-console
37 | `Find the server at: http://localhost:${app.get(
38 | "port"
39 | )}/`
40 | );
41 | });
42 |
--------------------------------------------------------------------------------
/testing/weather/src/assets/c.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/testing/weather/src/assets/c.png
--------------------------------------------------------------------------------
/testing/weather/src/assets/h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/testing/weather/src/assets/h.png
--------------------------------------------------------------------------------
/testing/weather/src/assets/hc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/testing/weather/src/assets/hc.png
--------------------------------------------------------------------------------
/testing/weather/src/assets/hr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/testing/weather/src/assets/hr.png
--------------------------------------------------------------------------------
/testing/weather/src/assets/lc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/testing/weather/src/assets/lc.png
--------------------------------------------------------------------------------
/testing/weather/src/assets/lr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/testing/weather/src/assets/lr.png
--------------------------------------------------------------------------------
/testing/weather/src/assets/s.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/testing/weather/src/assets/s.png
--------------------------------------------------------------------------------
/testing/weather/src/assets/sl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/testing/weather/src/assets/sl.png
--------------------------------------------------------------------------------
/testing/weather/src/assets/sn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/testing/weather/src/assets/sn.png
--------------------------------------------------------------------------------
/testing/weather/src/assets/t.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/testing/weather/src/assets/t.png
--------------------------------------------------------------------------------
/testing/weather/src/components/HomeContainer.vue:
--------------------------------------------------------------------------------
1 |
2 | Pick a city below to see the weather!
3 |
4 |
5 |
10 |
--------------------------------------------------------------------------------
/testing/weather/src/components/NotFoundContainer.vue:
--------------------------------------------------------------------------------
1 |
2 | Sorry, this route does not exist :(
3 |
4 |
5 |
10 |
--------------------------------------------------------------------------------
/testing/weather/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import App from './App';
3 | import router from './router';
4 | import store from './store';
5 |
6 | new Vue({
7 | router,
8 | store,
9 | render: h => h(App)
10 | }).$mount('#app');
11 |
--------------------------------------------------------------------------------
/testing/weather/src/router.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import VueRouter from 'vue-router';
3 | import HomeContainer from './components/HomeContainer.vue';
4 | import WeatherContainer from './components/WeatherContainer.vue';
5 | import NotFoundContainer from './components/NotFoundContainer.vue';
6 |
7 | Vue.use(VueRouter);
8 |
9 | const router = new VueRouter({
10 | mode: 'history',
11 | routes: [
12 | {
13 | path: '/',
14 | component: HomeContainer
15 | },
16 | {
17 | path: '/weather/:id',
18 | component: WeatherContainer,
19 | props: true,
20 | beforeEnter: (to, from, next) => {
21 | const id = to.params.id;
22 | if (
23 | ![
24 | 2459115,
25 | 468739,
26 | 2122265,
27 | 1118370,
28 | 1105779,
29 | 1398823
30 | ].includes(Number(id))
31 | ) {
32 | next("/not-found");
33 | } else {
34 | next();
35 | }
36 | }
37 | },
38 | {
39 | path: '*',
40 | component: NotFoundContainer
41 | }
42 | ]
43 | });
44 |
45 | export default router;
46 |
--------------------------------------------------------------------------------
/testing/weather/tests/unit/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | mocha: true
4 | }
5 | }
--------------------------------------------------------------------------------
/testing/weather/tests/unit/weather-1/App.spec.js:
--------------------------------------------------------------------------------
1 | import Vuex from 'vuex';
2 | import App from '@/App';
3 | import { shallowMount, createLocalVue } from '@vue/test-utils';
4 | import { expect } from 'chai';
5 |
6 | describe('App.vue', () => {
7 | let wrapper;
8 | let store;
9 | let getters;
10 |
11 | beforeEach(() => {
12 | const localVue = createLocalVue();
13 | localVue.use(Vuex);
14 |
15 | getters = {
16 | loading: () => { return false }
17 | }
18 |
19 | store = new Vuex.Store({
20 | getters
21 | });
22 |
23 | wrapper = shallowMount(App, {
24 | localVue,
25 | store,
26 | stubs: ['router-link', 'router-view']
27 | });
28 | });
29 |
30 | it("should display the current day's date", () => {
31 | const formattedDate = new Date().toDateString();
32 | expect(wrapper.html()).to.contain(formattedDate);
33 | });
34 | });
35 |
--------------------------------------------------------------------------------
/testing/weather/tests/unit/weather-1/components/HomeContainer.spec.js:
--------------------------------------------------------------------------------
1 | import HomeContainer from '@/components/HomeContainer';
2 | import {shallowMount} from '@vue/test-utils';
3 | import { expect } from 'chai';
4 |
5 | describe('HomeContainer.vue', () => {
6 | it('should display the appropriate index message', () => {
7 | const wrapper = shallowMount(HomeContainer);
8 | expect(
9 | wrapper.html()
10 | ).to.contain(
11 | 'Pick a city below to see the weather!
'
12 | );
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/testing/weather/tests/unit/weather-1/components/NotFoundContainer.spec.js:
--------------------------------------------------------------------------------
1 | import NotFoundContainer from '@/components/NotFoundContainer';
2 | import {shallowMount} from '@vue/test-utils';
3 | import { expect } from 'chai';
4 |
5 | describe('NotFoundContainer.vue', () => {
6 | it('should display the appropriate not found message', () => {
7 | const wrapper = shallowMount(NotFoundContainer);
8 | expect(
9 | wrapper.html()
10 | ).to.contain(
11 | 'Sorry, this route does not exist :(
'
12 | );
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/testing/weather/tests/unit/weather-1/components/WeatherContainer.spec.js:
--------------------------------------------------------------------------------
1 | describe('WeatherContainer.vue', () => {
2 |
3 | });
4 |
--------------------------------------------------------------------------------
/testing/weather/tests/unit/weather-2/components/HomeContainer.spec.js:
--------------------------------------------------------------------------------
1 | import HomeContainer from '@/components/HomeContainer';
2 | import {shallowMount} from '@vue/test-utils';
3 | import { expect } from 'chai';
4 |
5 | describe('HomeContainer.vue', () => {
6 | it('should display the appropriate index message', () => {
7 | const wrapper = shallowMount(HomeContainer);
8 | expect(
9 | wrapper.html()
10 | ).to.contain(
11 | 'Pick a city below to see the weather!
'
12 | );
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/testing/weather/tests/unit/weather-2/components/NotFoundContainer.spec.js:
--------------------------------------------------------------------------------
1 | import NotFoundContainer from '@/components/NotFoundContainer';
2 | import {shallowMount} from '@vue/test-utils';
3 | import { expect } from 'chai';
4 |
5 | describe('NotFoundContainer.vue', () => {
6 | it('should display the appropriate not found message', () => {
7 | const wrapper = shallowMount(NotFoundContainer);
8 | expect(
9 | wrapper.html()
10 | ).to.contain(
11 | 'Sorry, this route does not exist :(
'
12 | );
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/testing/weather/tests/unit/weather-2/components/WeatherContainer.spec.js:
--------------------------------------------------------------------------------
1 | describe('WeatherContainer.vue', () => {
2 |
3 | });
4 |
--------------------------------------------------------------------------------
/testing/weather/tests/unit/weather-3/components/HomeContainer.spec.js:
--------------------------------------------------------------------------------
1 | import HomeContainer from '@/components/HomeContainer';
2 | import {shallowMount} from '@vue/test-utils';
3 | import { expect } from 'chai';
4 |
5 | describe('HomeContainer.vue', () => {
6 | it('should display the appropriate index message', () => {
7 | const wrapper = shallowMount(HomeContainer);
8 | expect(
9 | wrapper.html()
10 | ).to.contain(
11 | 'Pick a city below to see the weather!
'
12 | );
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/testing/weather/tests/unit/weather-3/components/NotFoundContainer.spec.js:
--------------------------------------------------------------------------------
1 | import NotFoundContainer from '@/components/NotFoundContainer';
2 | import {shallowMount} from '@vue/test-utils';
3 | import { expect } from 'chai';
4 |
5 | describe('NotFoundContainer.vue', () => {
6 | it('should display the appropriate not found message', () => {
7 | const wrapper = shallowMount(NotFoundContainer);
8 | expect(
9 | wrapper.html()
10 | ).to.contain(
11 | 'Sorry, this route does not exist :(
'
12 | );
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/testing/weather/tests/unit/weather-complete/components/HomeContainer.spec.js:
--------------------------------------------------------------------------------
1 | import HomeContainer from '@/components/HomeContainer';
2 | import {shallowMount} from '@vue/test-utils';
3 | import { expect } from 'chai';
4 |
5 | describe('HomeContainer.vue', () => {
6 | it('should display the appropriate index message', () => {
7 | const wrapper = shallowMount(HomeContainer);
8 | expect(
9 | wrapper.html()
10 | ).to.contain(
11 | 'Pick a city below to see the weather!
'
12 | );
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/testing/weather/tests/unit/weather-complete/components/NotFoundContainer.spec.js:
--------------------------------------------------------------------------------
1 | import NotFoundContainer from '@/components/NotFoundContainer';
2 | import {shallowMount} from '@vue/test-utils';
3 | import { expect } from 'chai';
4 |
5 | describe('NotFoundContainer.vue', () => {
6 | it('should display the appropriate not found message', () => {
7 | const wrapper = shallowMount(NotFoundContainer);
8 | expect(
9 | wrapper.html()
10 | ).to.contain(
11 | 'Sorry, this route does not exist :(
'
12 | );
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/testing/weather/tests/unit/weather/App.spec.js:
--------------------------------------------------------------------------------
1 | describe('App.vue', () => {
2 |
3 | });
4 |
--------------------------------------------------------------------------------
/testing/weather/tests/unit/weather/components/HomeContainer.spec.js:
--------------------------------------------------------------------------------
1 | import HomeContainer from '@/components/HomeContainer';
2 | import {shallowMount} from '@vue/test-utils';
3 | import { expect } from 'chai';
4 |
5 | describe('HomeContainer.vue', () => {
6 | it('should display the appropriate index message', () => {
7 | const wrapper = shallowMount(HomeContainer);
8 | expect(
9 | wrapper.html()
10 | ).to.contain(
11 | 'Pick a city below to see the weather!
'
12 | );
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/testing/weather/tests/unit/weather/components/NotFoundContainer.spec.js:
--------------------------------------------------------------------------------
1 | import NotFoundContainer from '@/components/NotFoundContainer';
2 | import {shallowMount} from '@vue/test-utils';
3 | import { expect } from 'chai';
4 |
5 | describe('NotFoundContainer.vue', () => {
6 | it('should display the appropriate not found message', () => {
7 | const wrapper = shallowMount(NotFoundContainer);
8 | expect(
9 | wrapper.html()
10 | ).to.contain(
11 | 'Sorry, this route does not exist :(
'
12 | );
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/testing/weather/tests/unit/weather/components/WeatherContainer.spec.js:
--------------------------------------------------------------------------------
1 | describe('WeatherContainer.vue', () => {
2 |
3 | });
4 |
--------------------------------------------------------------------------------
/testing/weather/vue.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | devServer: {
3 | proxy: {
4 | '/api': {
5 | target: 'http://localhost:3000/',
6 | changeOrigin: true,
7 | pathRewrite: {
8 | '^/api': ''
9 | }
10 | }
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/upvote/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 |
9 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/upvote/app/main.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/upvote/app/main.js
--------------------------------------------------------------------------------
/upvote/app_1/main.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/upvote/app_1/main.js
--------------------------------------------------------------------------------
/upvote/app_2/main.js:
--------------------------------------------------------------------------------
1 | new Vue({
2 | el: '#app',
3 | data: {
4 | submissions: Seed.submissions
5 | }
6 | });
7 |
--------------------------------------------------------------------------------
/upvote/app_3/main.js:
--------------------------------------------------------------------------------
1 | new Vue({
2 | el: '#app',
3 | data: {
4 | submissions: Seed.submissions
5 | }
6 | })
7 |
--------------------------------------------------------------------------------
/upvote/app_4/main.js:
--------------------------------------------------------------------------------
1 | new Vue({
2 | el: "#app",
3 | data: {
4 | submissions: Seed.submissions
5 | },
6 | computed: {
7 | sortedSubmissions() {
8 | return this.submissions.sort((a, b) => {
9 | return b.votes - a.votes;
10 | });
11 | }
12 | },
13 | methods: {
14 | upvote(submissionId) {
15 | const submission = this.submissions.find(
16 | submission => submission.id === submissionId
17 | );
18 | submission.votes++;
19 | }
20 | }
21 | });
22 |
--------------------------------------------------------------------------------
/upvote/app_5/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 |
9 |
11 |
12 |
13 |
14 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/upvote/app_complete/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 |
9 |
11 |
12 |
13 |
14 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/upvote/public/images/avatars/daniel.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/upvote/public/images/avatars/daniel.jpg
--------------------------------------------------------------------------------
/upvote/public/images/avatars/kristy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/upvote/public/images/avatars/kristy.png
--------------------------------------------------------------------------------
/upvote/public/images/avatars/molly.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/upvote/public/images/avatars/molly.png
--------------------------------------------------------------------------------
/upvote/public/images/avatars/veronika.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/upvote/public/images/avatars/veronika.jpg
--------------------------------------------------------------------------------
/upvote/public/images/submissions/image-aqua.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/upvote/public/images/submissions/image-aqua.png
--------------------------------------------------------------------------------
/upvote/public/images/submissions/image-rose.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/upvote/public/images/submissions/image-rose.png
--------------------------------------------------------------------------------
/upvote/public/images/submissions/image-steel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/upvote/public/images/submissions/image-steel.png
--------------------------------------------------------------------------------
/upvote/public/images/submissions/image-yellow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/upvote/public/images/submissions/image-yellow.png
--------------------------------------------------------------------------------
/upvote/public/styles.css:
--------------------------------------------------------------------------------
1 | /* Miscellaneous Styles */
2 |
3 | .dividing-header {
4 | margin-top: 1em;
5 | margin-bottom: 2em;
6 | }
7 |
8 | .section {
9 | padding: 2rem 1.5rem;
10 | }
11 |
12 | .media {
13 | max-width: 600px;
14 | margin: 0 auto;
15 | border: 1px solid #e6e7e9;
16 | padding: 1em 1.5em 0.5em 1.5em;
17 | border-radius: 0.3em;
18 | }
19 |
20 | .media + .media {
21 | margin-top: 1.5rem;
22 | }
23 |
24 | .blue-border {
25 | border: 1px solid #3373dc !important;
26 | }
27 |
28 | .tag {
29 | font-size: 0.6rem !important;
30 | }
31 |
32 | .icon {
33 | cursor: pointer;
34 | }
35 |
36 | .image.is-24x24 {
37 | display: inline;
38 | position: relative;
39 | top: 5px;
40 | border-radius: 20px;
41 | }
--------------------------------------------------------------------------------
/vuex/note_taking/app-complete/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vuex: Note-taking
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
Notes
16 |
17 | {{ note }}
18 |
19 |
20 |
21 |
Timestamp
22 |
23 | {{ timestamp }}
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/vuex/note_taking/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vuex: Note-taking
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | Notes
16 |
17 |
18 | Timestamp
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/vuex/note_taking/app/main.js:
--------------------------------------------------------------------------------
1 | const inputComponent = {
2 | template: ``,
3 | }
4 |
5 | new Vue({
6 | el: '#app',
7 | components: {
8 | 'input-component': inputComponent
9 | }
10 | })
11 |
--------------------------------------------------------------------------------
/vuex/note_taking/public/styles.css:
--------------------------------------------------------------------------------
1 | html, body {
2 | height: 100%;
3 | }
4 |
5 | #app {
6 | height: inherit;
7 | margin: 0 auto;
8 | display: flex;
9 | flex-direction: column;
10 | align-items: center;
11 | -webkit-align-items: center;
12 | justify-content: center;
13 | -webkit-justify-content: center;
14 | }
15 |
16 | .notes-section {
17 | width: 500px;
18 | }
19 |
20 | .columns {
21 | width: 100%;
22 | }
23 |
24 | .notes, .timestamps {
25 | padding: 5px 0px;
26 | }
27 |
28 | .note-count {
29 | margin-top: 48px;
30 | }
--------------------------------------------------------------------------------
/vuex/shopping_cart/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 | # local env files
6 | .env.local
7 | .env.*.local
8 |
9 | # Log files
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 | *.suo
18 | *.ntvs*
19 | *.njsproj
20 | *.sln
21 | *.sw*
22 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/README.md:
--------------------------------------------------------------------------------
1 | # Fullstack Vue
2 |
3 | ## Vuex - Shopping Cart
4 |
5 | 1. Ensure you have `npm` installed.
6 |
7 | 2. Install the dependencies
8 |
9 | ````
10 | npm install
11 | ````
12 |
13 | 3. Boot the app
14 |
15 | ````
16 | npm run start
17 | ````
18 |
19 | The Node and Webpack servers are now running - watch the console output for instructions. Your entire application is now available at [http://localhost:8080/](http://localhost:8080/)
--------------------------------------------------------------------------------
/vuex/shopping_cart/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "shopping_cart",
3 | "description": "Project Four: Shopping Cart",
4 | "version": "1.0.0",
5 | "author": "Fullstack.io",
6 | "private": true,
7 | "scripts": {
8 | "start": "concurrently \"npm run server\" \"npm run serve\"",
9 | "server": "node server",
10 | "serve": "vue-cli-service serve",
11 | "build": "vue-cli-service build",
12 | "lint": "vue-cli-service lint"
13 | },
14 | "dependencies": {
15 | "vue": "^2.5.17",
16 | "vuex": "^3.0.1",
17 | "axios": "^0.18.0"
18 | },
19 | "devDependencies": {
20 | "@vue/cli-service": "^3.0.0",
21 | "@vue/cli-plugin-babel": "^3.0.0",
22 | "@vue/cli-plugin-eslint": "^3.0.0",
23 | "vue-template-compiler": "^2.5.17",
24 | "concurrently": "^3.6.1"
25 | },
26 | "eslintConfig": {
27 | "root": true,
28 | "env": {
29 | "node": true
30 | },
31 | "extends": [
32 | "plugin:vue/essential",
33 | "eslint:recommended"
34 | ],
35 | "rules": {},
36 | "parserOptions": {
37 | "parser": "babel-eslint"
38 | }
39 | },
40 | "postcss": {
41 | "plugins": {
42 | "autoprefixer": {}
43 | }
44 | },
45 | "browserslist": [
46 | "> 1%",
47 | "last 2 versions",
48 | "not ie <= 8"
49 | ]
50 | }
51 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/public/bulma/bulma.css.map:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/vuex/shopping_cart/public/bulma/bulma.css.map
--------------------------------------------------------------------------------
/vuex/shopping_cart/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/vuex/shopping_cart/public/favicon.ico
--------------------------------------------------------------------------------
/vuex/shopping_cart/public/font-awesome/HELP-US-OUT.txt:
--------------------------------------------------------------------------------
1 | I hope you love Font Awesome. If you've found it useful, please do me a favor and check out my latest project,
2 | Fort Awesome (https://fortawesome.com). It makes it easy to put the perfect icons on your website. Choose from our awesome,
3 | comprehensive icon sets or copy and paste your own.
4 |
5 | Please. Check it out.
6 |
7 | -Dave Gandy
8 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/public/font-awesome/fonts/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/vuex/shopping_cart/public/font-awesome/fonts/FontAwesome.otf
--------------------------------------------------------------------------------
/vuex/shopping_cart/public/font-awesome/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/vuex/shopping_cart/public/font-awesome/fonts/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/vuex/shopping_cart/public/font-awesome/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/vuex/shopping_cart/public/font-awesome/fonts/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/vuex/shopping_cart/public/font-awesome/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/vuex/shopping_cart/public/font-awesome/fonts/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/vuex/shopping_cart/public/font-awesome/fonts/fontawesome-webfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnWall2016/fullstack-vue-code/84b6928f0222763e0882e161edaabfe67810dfef/vuex/shopping_cart/public/font-awesome/fonts/fontawesome-webfont.woff2
--------------------------------------------------------------------------------
/vuex/shopping_cart/public/font-awesome/less/animated.less:
--------------------------------------------------------------------------------
1 | // Animated Icons
2 | // --------------------------
3 |
4 | .@{fa-css-prefix}-spin {
5 | -webkit-animation: fa-spin 2s infinite linear;
6 | animation: fa-spin 2s infinite linear;
7 | }
8 |
9 | .@{fa-css-prefix}-pulse {
10 | -webkit-animation: fa-spin 1s infinite steps(8);
11 | animation: fa-spin 1s infinite steps(8);
12 | }
13 |
14 | @-webkit-keyframes fa-spin {
15 | 0% {
16 | -webkit-transform: rotate(0deg);
17 | transform: rotate(0deg);
18 | }
19 | 100% {
20 | -webkit-transform: rotate(359deg);
21 | transform: rotate(359deg);
22 | }
23 | }
24 |
25 | @keyframes fa-spin {
26 | 0% {
27 | -webkit-transform: rotate(0deg);
28 | transform: rotate(0deg);
29 | }
30 | 100% {
31 | -webkit-transform: rotate(359deg);
32 | transform: rotate(359deg);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/public/font-awesome/less/bordered-pulled.less:
--------------------------------------------------------------------------------
1 | // Bordered & Pulled
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-border {
5 | padding: .2em .25em .15em;
6 | border: solid .08em @fa-border-color;
7 | border-radius: .1em;
8 | }
9 |
10 | .@{fa-css-prefix}-pull-left { float: left; }
11 | .@{fa-css-prefix}-pull-right { float: right; }
12 |
13 | .@{fa-css-prefix} {
14 | &.@{fa-css-prefix}-pull-left { margin-right: .3em; }
15 | &.@{fa-css-prefix}-pull-right { margin-left: .3em; }
16 | }
17 |
18 | /* Deprecated as of 4.4.0 */
19 | .pull-right { float: right; }
20 | .pull-left { float: left; }
21 |
22 | .@{fa-css-prefix} {
23 | &.pull-left { margin-right: .3em; }
24 | &.pull-right { margin-left: .3em; }
25 | }
26 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/public/font-awesome/less/core.less:
--------------------------------------------------------------------------------
1 | // Base Class Definition
2 | // -------------------------
3 |
4 | .@{fa-css-prefix} {
5 | display: inline-block;
6 | font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration
7 | font-size: inherit; // can't have font-size inherit on line above, so need to override
8 | text-rendering: auto; // optimizelegibility throws things off #1094
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/public/font-awesome/less/fixed-width.less:
--------------------------------------------------------------------------------
1 | // Fixed Width Icons
2 | // -------------------------
3 | .@{fa-css-prefix}-fw {
4 | width: (18em / 14);
5 | text-align: center;
6 | }
7 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/public/font-awesome/less/font-awesome.less:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
4 | */
5 |
6 | @import "variables.less";
7 | @import "mixins.less";
8 | @import "path.less";
9 | @import "core.less";
10 | @import "larger.less";
11 | @import "fixed-width.less";
12 | @import "list.less";
13 | @import "bordered-pulled.less";
14 | @import "animated.less";
15 | @import "rotated-flipped.less";
16 | @import "stacked.less";
17 | @import "icons.less";
18 | @import "screen-reader.less";
19 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/public/font-awesome/less/larger.less:
--------------------------------------------------------------------------------
1 | // Icon Sizes
2 | // -------------------------
3 |
4 | /* makes the font 33% larger relative to the icon container */
5 | .@{fa-css-prefix}-lg {
6 | font-size: (4em / 3);
7 | line-height: (3em / 4);
8 | vertical-align: -15%;
9 | }
10 | .@{fa-css-prefix}-2x { font-size: 2em; }
11 | .@{fa-css-prefix}-3x { font-size: 3em; }
12 | .@{fa-css-prefix}-4x { font-size: 4em; }
13 | .@{fa-css-prefix}-5x { font-size: 5em; }
14 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/public/font-awesome/less/list.less:
--------------------------------------------------------------------------------
1 | // List Icons
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-ul {
5 | padding-left: 0;
6 | margin-left: @fa-li-width;
7 | list-style-type: none;
8 | > li { position: relative; }
9 | }
10 | .@{fa-css-prefix}-li {
11 | position: absolute;
12 | left: -@fa-li-width;
13 | width: @fa-li-width;
14 | top: (2em / 14);
15 | text-align: center;
16 | &.@{fa-css-prefix}-lg {
17 | left: (-@fa-li-width + (4em / 14));
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/public/font-awesome/less/path.less:
--------------------------------------------------------------------------------
1 | /* FONT PATH
2 | * -------------------------- */
3 |
4 | @font-face {
5 | font-family: 'FontAwesome';
6 | src: url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}');
7 | src: url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype'),
8 | url('@{fa-font-path}/fontawesome-webfont.woff2?v=@{fa-version}') format('woff2'),
9 | url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff'),
10 | url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype'),
11 | url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg');
12 | // src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
13 | font-weight: normal;
14 | font-style: normal;
15 | }
16 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/public/font-awesome/less/rotated-flipped.less:
--------------------------------------------------------------------------------
1 | // Rotated & Flipped Icons
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); }
5 | .@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); }
6 | .@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); }
7 |
8 | .@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); }
9 | .@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); }
10 |
11 | // Hook for IE8-9
12 | // -------------------------
13 |
14 | :root .@{fa-css-prefix}-rotate-90,
15 | :root .@{fa-css-prefix}-rotate-180,
16 | :root .@{fa-css-prefix}-rotate-270,
17 | :root .@{fa-css-prefix}-flip-horizontal,
18 | :root .@{fa-css-prefix}-flip-vertical {
19 | filter: none;
20 | }
21 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/public/font-awesome/less/screen-reader.less:
--------------------------------------------------------------------------------
1 | // Screen Readers
2 | // -------------------------
3 |
4 | .sr-only { .sr-only(); }
5 | .sr-only-focusable { .sr-only-focusable(); }
6 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/public/font-awesome/less/stacked.less:
--------------------------------------------------------------------------------
1 | // Stacked Icons
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-stack {
5 | position: relative;
6 | display: inline-block;
7 | width: 2em;
8 | height: 2em;
9 | line-height: 2em;
10 | vertical-align: middle;
11 | }
12 | .@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x {
13 | position: absolute;
14 | left: 0;
15 | width: 100%;
16 | text-align: center;
17 | }
18 | .@{fa-css-prefix}-stack-1x { line-height: inherit; }
19 | .@{fa-css-prefix}-stack-2x { font-size: 2em; }
20 | .@{fa-css-prefix}-inverse { color: @fa-inverse; }
21 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/public/font-awesome/scss/_animated.scss:
--------------------------------------------------------------------------------
1 | // Spinning Icons
2 | // --------------------------
3 |
4 | .#{$fa-css-prefix}-spin {
5 | -webkit-animation: fa-spin 2s infinite linear;
6 | animation: fa-spin 2s infinite linear;
7 | }
8 |
9 | .#{$fa-css-prefix}-pulse {
10 | -webkit-animation: fa-spin 1s infinite steps(8);
11 | animation: fa-spin 1s infinite steps(8);
12 | }
13 |
14 | @-webkit-keyframes fa-spin {
15 | 0% {
16 | -webkit-transform: rotate(0deg);
17 | transform: rotate(0deg);
18 | }
19 | 100% {
20 | -webkit-transform: rotate(359deg);
21 | transform: rotate(359deg);
22 | }
23 | }
24 |
25 | @keyframes fa-spin {
26 | 0% {
27 | -webkit-transform: rotate(0deg);
28 | transform: rotate(0deg);
29 | }
30 | 100% {
31 | -webkit-transform: rotate(359deg);
32 | transform: rotate(359deg);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/public/font-awesome/scss/_bordered-pulled.scss:
--------------------------------------------------------------------------------
1 | // Bordered & Pulled
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-border {
5 | padding: .2em .25em .15em;
6 | border: solid .08em $fa-border-color;
7 | border-radius: .1em;
8 | }
9 |
10 | .#{$fa-css-prefix}-pull-left { float: left; }
11 | .#{$fa-css-prefix}-pull-right { float: right; }
12 |
13 | .#{$fa-css-prefix} {
14 | &.#{$fa-css-prefix}-pull-left { margin-right: .3em; }
15 | &.#{$fa-css-prefix}-pull-right { margin-left: .3em; }
16 | }
17 |
18 | /* Deprecated as of 4.4.0 */
19 | .pull-right { float: right; }
20 | .pull-left { float: left; }
21 |
22 | .#{$fa-css-prefix} {
23 | &.pull-left { margin-right: .3em; }
24 | &.pull-right { margin-left: .3em; }
25 | }
26 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/public/font-awesome/scss/_core.scss:
--------------------------------------------------------------------------------
1 | // Base Class Definition
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix} {
5 | display: inline-block;
6 | font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration
7 | font-size: inherit; // can't have font-size inherit on line above, so need to override
8 | text-rendering: auto; // optimizelegibility throws things off #1094
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/public/font-awesome/scss/_fixed-width.scss:
--------------------------------------------------------------------------------
1 | // Fixed Width Icons
2 | // -------------------------
3 | .#{$fa-css-prefix}-fw {
4 | width: (18em / 14);
5 | text-align: center;
6 | }
7 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/public/font-awesome/scss/_larger.scss:
--------------------------------------------------------------------------------
1 | // Icon Sizes
2 | // -------------------------
3 |
4 | /* makes the font 33% larger relative to the icon container */
5 | .#{$fa-css-prefix}-lg {
6 | font-size: (4em / 3);
7 | line-height: (3em / 4);
8 | vertical-align: -15%;
9 | }
10 | .#{$fa-css-prefix}-2x { font-size: 2em; }
11 | .#{$fa-css-prefix}-3x { font-size: 3em; }
12 | .#{$fa-css-prefix}-4x { font-size: 4em; }
13 | .#{$fa-css-prefix}-5x { font-size: 5em; }
14 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/public/font-awesome/scss/_list.scss:
--------------------------------------------------------------------------------
1 | // List Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-ul {
5 | padding-left: 0;
6 | margin-left: $fa-li-width;
7 | list-style-type: none;
8 | > li { position: relative; }
9 | }
10 | .#{$fa-css-prefix}-li {
11 | position: absolute;
12 | left: -$fa-li-width;
13 | width: $fa-li-width;
14 | top: (2em / 14);
15 | text-align: center;
16 | &.#{$fa-css-prefix}-lg {
17 | left: -$fa-li-width + (4em / 14);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/public/font-awesome/scss/_path.scss:
--------------------------------------------------------------------------------
1 | /* FONT PATH
2 | * -------------------------- */
3 |
4 | @font-face {
5 | font-family: 'FontAwesome';
6 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}');
7 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'),
8 | url('#{$fa-font-path}/fontawesome-webfont.woff2?v=#{$fa-version}') format('woff2'),
9 | url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'),
10 | url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'),
11 | url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg');
12 | // src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
13 | font-weight: normal;
14 | font-style: normal;
15 | }
16 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/public/font-awesome/scss/_rotated-flipped.scss:
--------------------------------------------------------------------------------
1 | // Rotated & Flipped Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); }
5 | .#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); }
6 | .#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); }
7 |
8 | .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); }
9 | .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); }
10 |
11 | // Hook for IE8-9
12 | // -------------------------
13 |
14 | :root .#{$fa-css-prefix}-rotate-90,
15 | :root .#{$fa-css-prefix}-rotate-180,
16 | :root .#{$fa-css-prefix}-rotate-270,
17 | :root .#{$fa-css-prefix}-flip-horizontal,
18 | :root .#{$fa-css-prefix}-flip-vertical {
19 | filter: none;
20 | }
21 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/public/font-awesome/scss/_screen-reader.scss:
--------------------------------------------------------------------------------
1 | // Screen Readers
2 | // -------------------------
3 |
4 | .sr-only { @include sr-only(); }
5 | .sr-only-focusable { @include sr-only-focusable(); }
6 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/public/font-awesome/scss/_stacked.scss:
--------------------------------------------------------------------------------
1 | // Stacked Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-stack {
5 | position: relative;
6 | display: inline-block;
7 | width: 2em;
8 | height: 2em;
9 | line-height: 2em;
10 | vertical-align: middle;
11 | }
12 | .#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x {
13 | position: absolute;
14 | left: 0;
15 | width: 100%;
16 | text-align: center;
17 | }
18 | .#{$fa-css-prefix}-stack-1x { line-height: inherit; }
19 | .#{$fa-css-prefix}-stack-2x { font-size: 2em; }
20 | .#{$fa-css-prefix}-inverse { color: $fa-inverse; }
21 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/public/font-awesome/scss/font-awesome.scss:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
4 | */
5 |
6 | @import "variables";
7 | @import "mixins";
8 | @import "path";
9 | @import "core";
10 | @import "larger";
11 | @import "fixed-width";
12 | @import "list";
13 | @import "bordered-pulled";
14 | @import "animated";
15 | @import "rotated-flipped";
16 | @import "stacked";
17 | @import "icons";
18 | @import "screen-reader";
19 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Project Four: Shopping Cart
9 |
10 |
11 |
12 |
13 |
14 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/server-cart-data.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": 1,
4 | "title": "The Fullstack Hoodie",
5 | "description": "Lightweight, breathable hoodie with the Fullstack Crest. Guaranteed to keep you looking fresh while warm.",
6 | "price": 19.99,
7 | "quantity": 2
8 | }
9 | ]
--------------------------------------------------------------------------------
/vuex/shopping_cart/server-product-data.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": 1,
4 | "title": "The Fullstack Hoodie",
5 | "description": "Lightweight, breathable hoodie with the Fullstack Crest. Guaranteed to keep you looking fresh while warm.",
6 | "price": 19.99
7 | },
8 | {
9 | "id": 2,
10 | "title": "The Fullstack Tee",
11 | "description": "The original Fullstack clothing item. Always prepared to keep your style in check.",
12 | "price": 15.99
13 | },
14 | {
15 | "id": 3,
16 | "title": "The Fullstack Fitted Cap",
17 | "description": "Stay comfortable and cool with the first Fullstack Fitted Cap, featuring a normal bill and medium crown.",
18 | "price": 15.99
19 | },
20 | {
21 | "id": 4,
22 | "title": "The Fullstack Jacket",
23 | "description": "Keep warm and protected with the rugged, durable Fullstack lightweight jacket.",
24 | "price": 49.99
25 | }
26 | ]
27 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/src/app-1/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
16 |
28 |
29 |
47 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/src/app-1/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import Vuex from 'vuex';
3 | import product from './modules/product';
4 | import cart from './modules/cart';
5 |
6 | Vue.use(Vuex);
7 |
8 | export default new Vuex.Store({
9 | modules: {
10 | product,
11 | cart
12 | }
13 | });
14 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/src/app-1/store/modules/cart/index.js:
--------------------------------------------------------------------------------
1 |
2 | const state = {};
3 |
4 | const mutations = {};
5 |
6 | const actions = {};
7 |
8 | const getters = {};
9 |
10 | const cartModule = {
11 | state,
12 | mutations,
13 | actions,
14 | getters
15 | }
16 |
17 | export default cartModule;
18 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/src/app-1/store/modules/product/index.js:
--------------------------------------------------------------------------------
1 |
2 | const state = {};
3 |
4 | const mutations = {};
5 |
6 | const actions = {};
7 |
8 | const getters = {};
9 |
10 | const productModule = {
11 | state,
12 | mutations,
13 | actions,
14 | getters
15 | }
16 |
17 | export default productModule;
18 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/src/app-2/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
16 |
28 |
29 |
47 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/src/app-2/components/product/ProductList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
14 |
15 | # of products: 4
16 |
17 |
18 |
19 |
20 |
37 |
38 |
56 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/src/app-2/components/product/ProductListItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ productItem.title }}
4 |
8 | Add to Cart
9 |
10 |
11 |
{{ productItem.description }}
12 |
13 | {{ productItem.price }}
14 |
15 |
16 |
17 |
18 |
24 |
25 |
30 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/src/app-2/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import Vuex from 'vuex';
3 | import product from './modules/product';
4 | import cart from './modules/cart';
5 |
6 | Vue.use(Vuex);
7 |
8 | export default new Vuex.Store({
9 | modules: {
10 | product,
11 | cart
12 | }
13 | });
14 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/src/app-2/store/modules/cart/index.js:
--------------------------------------------------------------------------------
1 | const state = {};
2 |
3 | const mutations = {};
4 |
5 | const actions = {};
6 |
7 | const getters = {};
8 |
9 | const cartModule = {
10 | state,
11 | mutations,
12 | actions,
13 | getters
14 | }
15 |
16 | export default cartModule;
17 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/src/app-2/store/modules/product/index.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | const state = {
4 | productItems: []
5 | }
6 |
7 | const mutations = {
8 | UPDATE_PRODUCT_ITEMS (state, payload) {
9 | state.productItems = payload;
10 | }
11 | }
12 |
13 | const actions = {
14 | getProductItems ({ commit }) {
15 | axios.get('/api/products').then((response) => {
16 | commit('UPDATE_PRODUCT_ITEMS', response.data)
17 | });
18 | }
19 | }
20 |
21 | const getters = {
22 | productItems: state => state.productItems
23 | }
24 |
25 | const productModule = {
26 | state,
27 | mutations,
28 | actions,
29 | getters
30 | }
31 |
32 | export default productModule;
33 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/src/app-3/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
16 |
28 |
29 |
47 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/src/app-3/components/cart/CartListItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ cartItem.title }}
4 |
5 |
6 |
7 |
8 |
9 |
10 | {{ cartItem.price }}$ each
11 |
12 |
13 | Quantity: {{ cartItem.quantity }}
14 |
15 |
16 |
17 |
18 |
19 |
25 |
26 |
32 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/src/app-3/components/product/ProductList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
11 |
12 | # of products: 4
13 |
14 |
15 |
16 |
17 |
36 |
37 |
55 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/src/app-3/components/product/ProductListItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ productItem.title }}
4 |
8 | Add to Cart
9 |
10 |
11 |
{{ productItem.description }}
12 |
13 | {{ productItem.price }}
14 |
15 |
16 |
17 |
18 |
24 |
25 |
30 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/src/app-3/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import Vuex from 'vuex';
3 | import product from './modules/product';
4 | import cart from './modules/cart';
5 |
6 | Vue.use(Vuex);
7 |
8 | export default new Vuex.Store({
9 | modules: {
10 | product,
11 | cart
12 | }
13 | });
14 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/src/app-3/store/modules/product/index.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | const state = {
4 | productItems: []
5 | }
6 |
7 | const mutations = {
8 | UPDATE_PRODUCT_ITEMS (state, payload) {
9 | state.productItems = payload;
10 | }
11 | }
12 |
13 | const actions = {
14 | getProductItems ({ commit }) {
15 | axios.get('/api/products').then((response) => {
16 | commit('UPDATE_PRODUCT_ITEMS', response.data)
17 | });
18 | }
19 | }
20 |
21 | const getters = {
22 | productItems: state => state.productItems
23 | }
24 |
25 | const productModule = {
26 | state,
27 | mutations,
28 | actions,
29 | getters
30 | }
31 |
32 | export default productModule;
33 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/src/app-complete/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
16 |
28 |
29 |
47 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/src/app-complete/components/cart/CartListItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ cartItem.title }}
4 |
5 |
7 |
9 |
10 |
11 |
12 | {{ cartItem.price }}$ each
13 |
14 |
15 | Quantity: {{ cartItem.quantity }}
16 |
17 |
18 |
19 |
20 |
21 |
35 |
36 |
42 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/src/app-complete/components/product/ProductList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
11 |
12 | # of products: 4
13 |
14 |
15 |
16 |
17 |
36 |
37 |
55 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/src/app-complete/components/product/ProductListItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ productItem.title }}
4 |
7 | Add to Cart
8 |
9 |
10 |
{{ productItem.description }}
11 |
12 | {{ productItem.price }}
13 |
14 |
15 |
16 |
17 |
30 |
31 |
36 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/src/app-complete/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import Vuex from 'vuex';
3 | import product from './modules/product';
4 | import cart from './modules/cart';
5 |
6 | Vue.use(Vuex);
7 |
8 | export default new Vuex.Store({
9 | modules: {
10 | product,
11 | cart
12 | }
13 | });
14 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/src/app-complete/store/modules/product/index.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | const state = {
4 | productItems: []
5 | }
6 |
7 | const mutations = {
8 | UPDATE_PRODUCT_ITEMS (state, payload) {
9 | state.productItems = payload;
10 | }
11 | }
12 |
13 | const actions = {
14 | getProductItems ({ commit }) {
15 | axios.get('/api/products').then((response) => {
16 | commit('UPDATE_PRODUCT_ITEMS', response.data)
17 | });
18 | }
19 | }
20 |
21 | const getters = {
22 | productItems: state => state.productItems
23 | }
24 |
25 | const productModule = {
26 | state,
27 | mutations,
28 | actions,
29 | getters
30 | }
31 |
32 | export default productModule;
33 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/src/app/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
16 |
28 |
29 |
49 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import App from './app-complete/App.vue';
3 | import store from './app-complete/store';
4 |
5 | new Vue({
6 | store,
7 | render: h => h(App)
8 | }).$mount('#app');
9 |
--------------------------------------------------------------------------------
/vuex/shopping_cart/vue.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | devServer: {
3 | proxy: {
4 | '/api': {
5 | target: 'http://localhost:3000/',
6 | changeOrigin: true,
7 | pathRewrite: {
8 | '^/api': ''
9 | }
10 | }
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------