├── .gitignore ├── README.md ├── index.html ├── package.json ├── src ├── App.vue ├── Compose.vue ├── Content.vue ├── Important.vue ├── Inbox.vue ├── Messages.vue ├── Sent.vue ├── Sidebar.vue ├── Trash.vue ├── ViewMessage.vue ├── assets │ ├── css │ │ └── style.css │ └── images │ │ └── profile.jpg ├── data │ ├── messages.js │ └── random-messages.js └── main.js └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .idea 3 | .DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Vue.js Mail Example Application 2 | 3 | This repository contains the code for the second example application from the [Vue.js: From Beginner to Professional course](https://l.codingexplained.com/r/vuejs-course?src=github). 4 | 5 | ## Getting up and Running 6 | 7 | ``` bash 8 | # Install the dependencies 9 | npm install 10 | 11 | # Serve with hot reload at http://localhost:8080 12 | npm run dev 13 | 14 | # Build for production with minification 15 | npm run build 16 | ``` 17 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |6 | | 7 | 8 | 9 | 10 | | 11 |{{ message.from.name }} | 12 |{{ message.subject }} | 13 |14 | | {{ message.date.fromNow() }} | 15 |
No messages here yet.
20 | 21 | 22 | -------------------------------------------------------------------------------- /src/Sent.vue: -------------------------------------------------------------------------------- 1 | 2 |Date: {{ data.message.date.fromNow() }}
24 |From: {{ data.message.from.name }} <{{ data.message.from.email }}>
25 |Hello,
8 |You recently completed a purchase, and we'd like to know how we did. Your feedback is very important to us!
9 |Please click the following link to complete the survey. We're not going to lie, it will take way more than 5 minutes.
10 | 11 | `, 12 | isImportant: false, 13 | isDeleted: false, 14 | isRead: false, 15 | type: 'incoming', 16 | date: moment().subtract(10, 'minutes'), 17 | from: { 18 | name: 'SurveyDonkey.com', 19 | email: 'survey@surveydonkey.com' 20 | }, 21 | attachments: [] 22 | }, 23 | { 24 | subject: 'Login from new device', 25 | content: ` 26 |Hello Bo,
27 |We noticed that your account was used to sign in from a new device, and we're pretty worried about it.
28 |It looks like the login came from Moscow, Russia, so unless you are on vacation, you're probably in big trouble.
29 |We just thought we'd let you know.
30 |Good luck with that!
31 |Google Security Team
32 | `, 33 | isImportant: false, 34 | isDeleted: false, 35 | isRead: false, 36 | type: 'incoming', 37 | date: moment().subtract(30, 'minutes'), 38 | from: { 39 | name: 'Google', 40 | email: 'security@accounts.google.com' 41 | }, 42 | attachments: [] 43 | }, 44 | { 45 | subject: 'Your password has been reset', 46 | content: ` 47 |Hello Bo,
48 |This is just to notify you that someone (hopefully you) has reset your Facebook password.
49 |The Facebook Team
50 | `, 51 | isImportant: true, 52 | isDeleted: false, 53 | isRead: true, 54 | type: 'incoming', 55 | date: moment().subtract(75, 'minutes'), 56 | from: { 57 | name: 'Facebook', 58 | email: 'no-reply@facebook.com' 59 | }, 60 | attachments: [] 61 | }, 62 | { 63 | subject: 'Booking confirmation #52798', 64 | content: ` 65 |Hello Bo,
66 |Thank you for booking your stay on Hotels.com.
67 |You will find your reservation details attached to this message.
68 |We hope that you enjoy your stay!
69 | `, 70 | isImportant: true, 71 | isDeleted: false, 72 | isRead: true, 73 | type: 'incoming', 74 | date: moment().subtract(2, 'days'), 75 | from: { 76 | name: 'Hotels.com', 77 | email: 'booking@hotels.com' 78 | }, 79 | attachments: [ 80 | { 81 | fileName: 'booking.pdf', 82 | size: 1000000 83 | } 84 | ] 85 | }, 86 | { 87 | subject: "Hey, what's up?", 88 | content: ` 89 |Hey, want to grab a cup of coffee soon?
90 |Let me know if you get this, because who really uses e-mail these days?
91 | `, 92 | isDeleted: false, 93 | type: 'outgoing', 94 | date: moment().subtract(7, 'days'), 95 | from: { 96 | name: 'Bo Andersen', 97 | email: 'fake@codingexplained.com' 98 | }, 99 | attachments: [] 100 | }, 101 | { 102 | subject: 'Thank you for your purchase', 103 | content: ` 104 |Thank you!
105 |We have received your payment, and your products are on the way!
106 |Order ID: ABCD1234
107 | `, 108 | isImportant: false, 109 | isDeleted: false, 110 | isRead: true, 111 | type: 'incoming', 112 | date: moment().subtract(2, 'weeks'), 113 | from: { 114 | name: 'Amazon', 115 | email: 'orders@amazon.com' 116 | }, 117 | attachments: [ 118 | { 119 | fileName: 'order.pdf', 120 | size: 2000000 121 | } 122 | ] 123 | }, 124 | { 125 | subject: 'Please activate your account', 126 | content: ` 127 |You recently signed up for Skype, and you need to activate your account.
128 |You can do this by clicking the below link, which expires in 10 seconds, so you better hurry!
129 | 130 |Hope you made it!
131 |The Skype Team
132 | `, 133 | isImportant: true, 134 | isDeleted: false, 135 | isRead: true, 136 | type: 'incoming', 137 | date: moment().subtract(2, 'months'), 138 | from: { 139 | name: 'Skype', 140 | email: 'accounts@skype.com' 141 | }, 142 | attachments: [] 143 | }, 144 | { 145 | subject: 'Get More Traffic to Your Website', 146 | content: ` 147 |Hello,
148 |This is clearly spam, and we don't even know your name. But since you don't have a spam filter, we thought we'd try to trick you into clicking the below phishing link.
149 |Oh, by the way, you are visitor number 1,000,000,000 on some unknown website, so you just won one billion dollars. True story, just click the link now!
150 | 151 | `, 152 | isImportant: false, 153 | isDeleted: true, 154 | isRead: false, 155 | type: 'incoming', 156 | date: moment().subtract(3, 'months'), 157 | from: { 158 | name: 'We Spam, inc.', 159 | email: 'scam@spam.com' 160 | }, 161 | attachments: [] 162 | }, 163 | { 164 | subject: 'Collaboration', 165 | content: ` 166 |Hey Adam,
167 |I would like to talk with you about a possible collaboration. I think we would both benefit from working together.
168 |Let me know if you are interested in having a word.
169 |Best regards,
170 |Bo Andersen
171 | `, 172 | isDeleted: false, 173 | type: 'outgoing', 174 | date: moment().subtract(100, 'days'), 175 | from: { 176 | name: 'Bo Andersen', 177 | email: 'fake@codingexplained.com' 178 | }, 179 | attachments: [] 180 | }, 181 | { 182 | subject: 'I want to buy your guitar', 183 | content: ` 184 |Hey there!
185 |I saw that you have a guitar on sale. I never played an instrument, but I figured I'd be super good at it.
186 |Even though I know it's extremely annoying, I'm just going to ask "how much?"
187 |Let me know!
188 | `, 189 | isDeleted: false, 190 | type: 'outgoing', 191 | date: moment().subtract(4, 'months'), 192 | from: { 193 | name: 'Bo Andersen', 194 | email: 'fake@codingexplained.com' 195 | }, 196 | attachments: [] 197 | }, 198 | { 199 | subject: 'Remember your event on Tuesday', 200 | content: ` 201 |This is a reminder that you have registered for an event at the local tax authorities on Tuesday.
202 |Perhaps you thought you paid a lot of taxes, living in the world's most expensive country. But no, we have a little surprise for you.
203 |Can't wait to see you there!
204 | `, 205 | isImportant: false, 206 | isDeleted: true, 207 | isRead: true, 208 | type: 'incoming', 209 | date: moment().subtract(5, 'months'), 210 | from: { 211 | name: 'Tax Authorities', 212 | email: 'taxes@we-want-your-money.com' 213 | }, 214 | attachments: [ 215 | { 216 | fileName: 'invite.ics', 217 | size: 500000 218 | } 219 | ] 220 | }, 221 | { 222 | subject: 'Wrong Delivery', 223 | content: ` 224 |Hey,
225 |I ordered a pizza from you guys yesterday. I ordered a vegetarian one, but you delivered a meat lover's pizza.
226 |I only noticed this half way through eating it, so obviously I am quite upset about that.
227 |Please deliver a new pizza tonight, but this time a vegetarian one, but with bacon.
228 |Regards,
229 |An Angry Customer
230 | `, 231 | isDeleted: false, 232 | type: 'outgoing', 233 | date: moment().subtract(6, 'months'), 234 | from: { 235 | name: 'Bo Andersen', 236 | email: 'fake@codingexplained.com' 237 | }, 238 | attachments: [] 239 | }, 240 | { 241 | subject: 'Looking for a developer', 242 | content: ` 243 |Hey Bo,
244 |We are looking for a developer who knows Elasticsearch and Vue.js. Would you be interested in hearing more about it?
245 |This is obviously just a message that I sent to hundreds of other people without checking out their CV first.
246 |Let me know if you are open to talking about it.
247 |Best regards,
248 |A random recruiter
249 | `, 250 | isImportant: false, 251 | isDeleted: false, 252 | isRead: false, 253 | type: 'incoming', 254 | date: moment().subtract(7, 'months'), 255 | from: { 256 | name: 'Random Recruiter', 257 | email: 'random@recruiter.com' 258 | }, 259 | attachments: [ 260 | { 261 | fileName: 'job-description.pdf', 262 | size: 3000000 263 | } 264 | ] 265 | }, 266 | { 267 | subject: 'Your video is live!', 268 | content: ` 269 |Hey Coding Explained,
270 |Your video titled "Why Vue.js is Awesome" is now live on YouTube!
271 |You can find it here: https://youtu.be/watch?v=hg23hgls
272 | `, 273 | isImportant: false, 274 | isDeleted: false, 275 | isRead: true, 276 | type: 'incoming', 277 | date: moment().subtract(8, 'months'), 278 | from: { 279 | name: 'YouTube', 280 | email: 'video@youtube.com' 281 | }, 282 | attachments: [] 283 | }, 284 | { 285 | subject: "Here's what you missed", 286 | content: ` 287 |Hey Bo,
288 |In case you missed what happened on Slack yesterday, here you go.
289 |We choose to believe that you went on a vacation or something, since you didn't open up the app.
290 |You should probably check that out. Just sayin'.
297 |The Slack Team
298 | `, 299 | isImportant: false, 300 | isDeleted: false, 301 | isRead: true, 302 | type: 'incoming', 303 | date: moment().subtract(9, 'months'), 304 | from: { 305 | name: 'Slack', 306 | email: 'notifications@slack.com' 307 | }, 308 | attachments: [] 309 | }, 310 | { 311 | subject: 'Thank you for your purchase', 312 | content: ` 313 |Thank you for your purchase at SoundGear.com
314 |You bought the following item:
315 |Hello Bo,
8 |Thank you for subscribing to our newsletter!
9 |Before we can start spamming your mailbox, please confirm your subscription by clicking the below link.
10 | 11 |Thanks again!
12 | `, 13 | isImportant: false, 14 | isDeleted: false, 15 | isRead: false, 16 | type: 'incoming', 17 | date: moment(), 18 | from: { 19 | name: 'Coding Explained', 20 | email: 'irony@codingexplained.com' 21 | }, 22 | attachments: [] 23 | }, 24 | { 25 | subject: 'CrunchBase Daily', 26 | content: ` 27 |Here's what happened yesterday.
28 |Try to pay more attention next time.
34 | `, 35 | isImportant: false, 36 | isDeleted: false, 37 | isRead: false, 38 | type: 'incoming', 39 | date: moment(), 40 | from: { 41 | name: 'CrunchBase', 42 | email: 'daily@crunchbase.com' 43 | }, 44 | attachments: [] 45 | }, 46 | { 47 | subject: 'Design', 48 | content: ` 49 |Hey Bo, here's the design that you requested.
50 |Let me know what you think. Hope you like it!
51 |Sarah
52 | `, 53 | isImportant: false, 54 | isDeleted: false, 55 | isRead: false, 56 | type: 'incoming', 57 | date: moment(), 58 | from: { 59 | name: 'Sarah', 60 | email: 'sarah-designer@gmail.com' 61 | }, 62 | attachments: [ 63 | { 64 | fileName: 'design.psd', 65 | size: 14700000 66 | } 67 | ] 68 | } 69 | ] -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | 4 | export const eventBus = new Vue(); 5 | 6 | new Vue({ 7 | el: '#app', 8 | render: h => h(App) 9 | }) 10 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var webpack = require('webpack') 3 | 4 | module.exports = { 5 | entry: './src/main.js', 6 | output: { 7 | path: path.resolve(__dirname, './dist'), 8 | publicPath: '/dist/', 9 | filename: 'build.js' 10 | }, 11 | module: { 12 | rules: [ 13 | { 14 | test: /\.vue$/, 15 | loader: 'vue-loader', 16 | options: { 17 | loaders: { 18 | // Since sass-loader (weirdly) has SCSS as its default parse mode, we map 19 | // the "scss" and "sass" values for the lang attribute to the right configs here. 20 | // other preprocessors should work out of the box, no loader config like this nessessary. 21 | 'scss': 'vue-style-loader!css-loader!sass-loader', 22 | 'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax' 23 | } 24 | // other vue-loader options go here 25 | } 26 | }, 27 | { 28 | test: /\.js$/, 29 | loader: 'babel-loader', 30 | exclude: /node_modules/ 31 | }, 32 | { 33 | test: /\.(png|jpg|gif|svg)$/, 34 | loader: 'file-loader', 35 | options: { 36 | name: '[name].[ext]?[hash]' 37 | } 38 | } 39 | ] 40 | }, 41 | resolve: { 42 | alias: { 43 | 'vue$': 'vue/dist/vue.common.js' 44 | } 45 | }, 46 | devServer: { 47 | historyApiFallback: true, 48 | noInfo: true 49 | }, 50 | performance: { 51 | hints: false 52 | }, 53 | devtool: '#eval-source-map' 54 | } 55 | 56 | if (process.env.NODE_ENV === 'production') { 57 | module.exports.devtool = '#source-map' 58 | // http://vue-loader.vuejs.org/en/workflow/production.html 59 | module.exports.plugins = (module.exports.plugins || []).concat([ 60 | new webpack.DefinePlugin({ 61 | 'process.env': { 62 | NODE_ENV: '"production"' 63 | } 64 | }), 65 | new webpack.optimize.UglifyJsPlugin({ 66 | sourceMap: true, 67 | compress: { 68 | warnings: false 69 | } 70 | }), 71 | new webpack.LoaderOptionsPlugin({ 72 | minimize: true 73 | }) 74 | ]) 75 | } 76 | --------------------------------------------------------------------------------