 So, imagine you're on your way to a conference, and you know you will hear great talks by inspiring speakers, you know you will meet amazing new people you might want to connect with later, you want to snap some pictures so you can convince your co-workers to come, so you decide to go into your terminal and type Ember new conference tracker. I imagine if you're this kind of a person by the end of the conference you've typed this command at least two or three more times, and the next year you're at the conference you probably realize that you have not finished any of these projects. Today I would like to give you a blueprint to a finished project. I'm Anne Gereed, Scholt van Herijnen, and I'm from a city in the east of the Netherlands. I've been involved in the volunteering part of Embers in 2018. You might have seen me walk around in a Zoe suit at this conference. You might see me walk around during the snack break later. In my day-to-day job I'm not an Ember developer, I'm a team coach, so I help people communicate and collaborate, and I'm part of our diversity and inclusion initiative. In my free time that I still have some of, I am painting and drawing a lot. I yesterday painted my 305th animal since 19 September. We have a dog, her name is Izzy, you can find her in Scrimp, and we is me and Nick Scholt because we married two years ago. He will give a great workshop about animation later, and he's basically the reason I'm standing here because he brought me here when he got to speak here in 2018. So let's get back on topic. Imagine you want to build this lighthouse, and you're like me, and you have a lot of hobbies and your full-time job is not an Ember, so your lighthouse has to wait a bit. We're going to take a block of time, probably a Saturday or Sunday in which we have some free hours, and we're going to build the ground floor with the door. We're going to make sure that we build something that's done and useful, and then two weeks later we're going to take another block of time, and we're going to build the window, and then probably at some point you decide to spend a whole weekend on it and build the finishing part for your project. The thing you have to keep in mind to finish your project is, first of all, purpose. What is your project going to do, why are you building it, sometimes even for whom, and you want to try to keep it as simple as possible. During those tiny windows of time, you want to focus on making the minimal viable product, and not the minimal viable product we usually make when we're developing for our bosses, but really the minimal viable product. We're going to try to make our increments as small as possible, and we're going to keep reminding ourselves that it's a hobby project, so ugly is okay. And we're going to use tools that bring us joy and will set us up for success, so being at an Ember conference, of course that's Ember, we're going to use the linting that we've seen something about today already, CSS, and of course, Git. So you might wonder why would I use Ember for my fun projects. Sadly, a lot of people already mentioned good things during this conference, so the fact that everything is there out of the box, I don't have to install a separate router, or there are a lot of things that I get when I type in Ember new. There is great documentation being on the learning team, of course I had to say that. And of course we have our great community where there are always people to help, so definitely a shout out to Preston who's always there, no matter your time zone on Discord, to help you with your problems. Today I would like to talk to you about these three apps. There are web apps that I build starting in 2001, and they have something in common, and that's that they're all single feature apps, shout out to Chris Manson. The idea behind the single feature app is that it does one thing and it does that well. So the first thing I want to tell you about is SET, and it's a card game, as you can see here, this is on our dining room table. And if you don't know, the goal is to find more SETs quicker than your opponent. And as we've heard a few times already, we had kind of a pandemic, so I wanted to play SET with my sister during the pandemic, and we tried that with a face down camera and face time, but latency was not great. So I said I can build that. So I started Ember New SET game, and started with my initial commit. So my first focus block is playing SET, and for you who don't know, SET consists of cards who have four properties. So they have a shape, they can be diamond, oval, and waves. They have fillings, solid, half, or empty. They have a different amount, so one, two, or three. And they have four different colors, green, red, and purple. And if you combine this, we get 81 images. So we have the 81 images here, so my second commit was add these images. I set myself up to make as tiny increments as possible with readable commit messages. So we have these cards, or these images, and now we need to build the logic. So something is a SET if three cards return true for all the properties. And a property is true if it's either all the same or they're all different. So if it's a wave, they should either be all waves, or it should be a wave, a diamond, and an oval. So with the logic part of it done, we move on to the interface. And this was the interface that we first released. So this is just your basic HTML. There is no styling yet, because that's not the focus. We wanted to ship our MVP as ugly as possible. So we have an unclick that will start the game, and once the game is started, it will show you this field. And this field is iterating over the cards that are in the field, and it renders them as an image tag with an unclick attribute. And this screenshot looks kind of nice, but as we know, we have Ember template lin that will show me here that I forgot to include an alt attribute, and really sorry, Mel, and I'm adding interaction to a noninteractive element. The cool thing is that I did not have to install this to become aware of the accessibility and usability issues that might have been in my code. So after fixing those, we were able to place it. So as you can see here, we're going to click on cards, and if they're valid, I will disappear, and if I click on invalid set, which I'm going to do now, it will say loser in the console, which is a nice way to encourage you to do better. But it did not remove this thing. So this is what we call an MVP, because it starts the game. It removes the valid sets, and it errors at invalid sets. This was 214 lines of code, and my sister and I both played this. As you can see here, there's one more commit that day. That was because there was no end state, so you had to hard refresh to restart the game. But that's fine, because the MVP was being able to play set, not to play set two times in a row. The next focus was playing together, because that was the thing I wanted to play with my sister. Being at a tech conference, I luckily don't have to explain to you that we have these cool technical things like web sockets that we can use to do some communication, and I went down that rabbit hole, and I'm not a developer by day, and I went down this rabbit hole. I had no great way to deploy it, and I thought, this is not bringing me joy, and it's not bringing me closer to my finished project, so I decided to pivot. And I implemented high scores so that I could text my sister how fast I did it, and she could text me back how fast she was. So we're using the track system for Ember to show our time and the high scores, and if we finish a game, we're going to update the high scores. We're using Ember concurrency, the add-on to have the timer update and go, and then we're using the web API's local storage to set and retrieve these high scores. And the cool thing is that I did not have to do anything really complicated to finish my focus and my purpose, basically, being able to play this with my sister. So this was done. And then I realized that for me and my sister, this was done. But for a friend of mine, he has difficulty seeing the distinction between red and green, so playing the real-life set for him is not possible. So I decided to simulate with the Firefox accessibility tools what it looks like currently. Then I decided to implement these three colored squares that allow you to click on them, and they're a color picker, yet again, a cool add-on that somebody in the community made that allows a user to pick colors that work for them. So we're going to include the Ember picker here, and it allows you to update the color. We're using, by now, SVGs instead of static PNGs so that we can actually give the user the color they really want. So by now, we finished it. And when it comes to the purpose, you don't want to overcomplicate. When it comes to focus, you want to keep thinking about future use. So I could have written the color picker myself, but that would have been, like, techdabs for me to maintain. I decided that I'm allowed to pivot instead of building web sockets. I decided to build high scores, and I used linting and useful add-ons to provide a good user experience for me and my users. So the next app is more of an app that you might build at work. It's about hydrogen fueling stations, and I looked it up. There are some in California and some in Canada, and that's it, like, on this part of the world. But my dad drives one of these, so he came to me with the question, can you please build me an app for Dutch hydrogen car drivers that shows up-to-date price information readable on their phone? Because up to this point, there was an app that apparently did not work to his liking. The website version of that was not responsive. And the only thing that was there that was readable on his phone was a guy who would update a table in a WordPress website. So I said, cool, let's go for this. So we have here my part of the log, and it's, again, these tiny increments that I'm doing. So we're going to start with the first one, building an MVP with static data. So what I did was copy the JSON block from one of the websites, and I pasted it into my application route model, and I kind of manufactured it into the information that I need to show or my dad wants to see. And the cool thing with this is that it allowed me to work on the front end separately from, like, what the API was providing me. So with this being in our model, we are going to iterate over that model, and for each station we've created a list item component that shows these tiny cards. And this had to be readable on people's phones. So when it comes to responsiveness, there are basically two kind of CSS properties that might come to your mind. So we have display flex and display grid, and I quickly want to show you the difference because both of them might work for your use case, but they do something different. So here they're still the same, the screen a bit wider is still the same, but when it comes to, like, more full width kind of thing, they do different things. So keep that in mind when you're trying to build a responsive layout. So for display grid, we're using the repeat auto fit, so it will fit as many of it in a row as it can. We say it has to be at least 275 pixels, but other than that, you can't figure it out. And for the display flex, we say flex wrap so that it actually wraps onto the next row, and for the children, we say that it can grow, but the basis should be 275 pixels. So they behave quite similarly, but especially on a full screen, they all look different. For this one, I went with display grid. To make it an extra mobile experience, we're using Ember web app, the add-on that will generate a manifest for you that allows you to pin the apps to your home screen without all the browser information being there, and it allows you to set the icons. If you're looking for a menu, which I did not need for any of the apps that I'm showing, but for this one, I did, there's Ember mobile menu that provides you with native gestures in your browser for people to use. So with this, I provided a native experience with a web app for the Dutch hydrogen card drivers. So the next thing is up-to-date price information, and for this, I use Netlify functions. I deploy all my hobby projects to Netlify, as long as I don't have too many, it's still free, and the cool thing about Netlify functions is that if you, it lets you deploy server-side code that behaves like an API endpoint. So here we have the Netlify function where I paste it in the URL of the call that I'm making. We're gonna fetch the data, and we're gonna kind of filter that data here already and then send it to our Ember app, and we're making sure that in the development, we're talking to our local version of it, and in production, we're talking to the deployed version of it, and that gives us this cool version with up-to-date information. Tiny disclaimer. This was a picture that I took at the airport, because my dad, just before we flew here, told me, hey, it's broken, because the API changed. I managed to fix it before the flight, so if you now go to it, you will actually see, again, working data, but that's the thing if you're talking to somebody else's API, they might change it. With it being summer, and Dutch people like to go on vacation, we had to expand, because up to now, we were only showing this part of Europe, and not really this part, but like even a tinier circle, but that was not really sure, but we wanted to include all the information possible. So we decided to skip the filter on the Netherlands version, and we made a Europe page that has these buttons for every country, and if you click on it, it will filter the list. That's trivial, but the cool thing here is this tiny flag, because it gives kind of a possess to the country, because most of the countries are proud of their flag, maybe especially here. So the cool thing about flag emojis is that they are unicode characters, so we're going to start here as a unicode index, and we're going to add two letters from each country code, and they make this emoji. So in this case, if you add the N and the L together, you'll get the Dutch flag, and this is a helper that I use for this. So as we expand, if there are new countries added to the list to the API, it will just automatically add the correct flag to them. Then comes the point that I'm really happy about and always makes my heart jump with joy is focused a bit on the design, because ugly is okay, but designing stuff brings me joy. So we're going to make sure that if we focus on design, we're setting ourselves up for success. For example, using CSS variables to create a limited color palette that we can just use as we go, so we don't have to every time think about which color I'm now going to pick. We have a primary color, we have a light version of it, a secondary color, and a light version of it, and probably you need some kind of gray that isn't too light, but definitely gray. So we use this color palette throughout the app. If you've been paying attention to the iterations that I've shown so far, you've seen that we've improved the icon. The icon first had a tiny number in there where the number is really important. Then we made the number bigger, but it was still against the blue background. And then the latest version, we decided to move the number into its own, it's now a span, and we gave it a lot of contrast so that you see the thing that matters. And then we just saw the Europe selection thing, and we made it chips that have an active state. If you selected them instead of being buttons that did a magic thing. And since this is mostly a mobile app, I did not implement a Hoover state because you don't have that. And that way I kept it simpler for myself. So the last thing that's important when we come to driving a car and filling it up somewhere is to see what's close to me. Because you don't want to end up driving to Amsterdam when there's something really close to you. So we use an Ember service for this that uses a web API called navigator to get your current position. And based on that current position in coordinates, we can do some math so we can calculate as the crow flies. And we can again use Ember concurrency to update this position as we go. So as you saw here, we've expanded throughout. So we started with just the Dutch stations and we expanded some of our functionality still serving our single purpose, allowing the hydrogen drivers to drive their car. We started small with static data and we've elaborated on that. And we use CSS variables and the browser APIs to push our app forward. The last app I want to tell you about is my Advent of Codes record. Advent of Code is an Advent calendar with programming puzzles. So if you're in that kind of thing, Advent of Code is definitely for you. So I wanted a place where I could share my solutions with the world, especially my brother and my father because we're doing this together. And have a nice place that would actually run my code and see if it's correct. And since I'm doing this in JavaScript, what better way is there than an Ember app? So I created this Ember app that would show you the day. You can click on the link to the actual exercise. And you have a toggle to toggle between the example input and your real often much larger input. And we can show the code because somebody in an orange shirt build a great item for that Ember code snippet. That allows me to write the code in the controller and then put it here without having to copy, paste it over. And as Ignace already told us today, copy, pasting things over is really annoying. So I was happy that I could just with invoking this angle bracket component show it here. This works nice, but every day I had to create the same files because we needed a route for day 12 and we needed a template for day 12 and we needed a controller for day 12. Luckily Ember has something for that, namely generators. So in our day-to-day, we use Ember G route somewhere or Ember G component, but we can also generate a blueprint which allows us then to use the name of that blueprint to actually type Ember G, so we made a blueprint called puzzle. You get for free this cool blueprint folder. In that blueprint folder, there's a files folder and an index.js. In the files folder, we have our app structure and in that app structure, we can insert files that will be inserted into our real app if we run the generator. So in this case, we have a template slash puzzles, underscore underscore name underscore underscore dot hbs, and the name will be replaced with the thing we tell the generator. So here we tell Ember G puzzle one. So we get in our templates folder in a real app, an hbs one dot hbs file that has the correct day number. And the same thing will happen for this controller. So here it will replace all the purple names with the number of the day and by that showing the correct solution if we click the button. This is nice because we've now like added these files automatically, but we also want to add, adapt some files. So for that, there's the index.js file that allows us to insert into a file that already exists. In this case, our application dot hbs, a link to component to the day we made. And since the day is the number, we can install like add this after the day minus one. This kind of assumes that you do it every day, but since it's my own hobby project, that's fine. The cool thing about making a generator this way is that it will show up if you type in ember generate dash dash help. It also shows all the other generators you can use with a bit of information. So here you can say, hey, from my project we have the puzzle generator and that just takes a name attribute. So here the purpose wasn't to improve the app. The purpose was to reduce the workload by working smarter so that I had time every day and energy to work on the solutions for the actual project instead of spending time copy pasting everything and often sloppy pasting everything. So we again used the useful add on that allow me to share the code, but we also use these generators quite easily to provide us with something that we otherwise would have typed again and again and again. So what is the blueprint to a finished project? Give yourself a purpose to work towards and try to keep it small. Make sure that you set yourself a focus during your time box to make the smallest increment possible towards your goal and make sure you use tools that bring you joy. Thank you very much for listening. If you want to see kind of the basic layout of my app you can go to the Ember sample apps GitHub. That's another initiative by Mel where you can see some tiny apps. And if you have a cool sample app you can edit there too. Nick is now gonna paste in Discord the link to the resources. There is more information there to all the things that I've used in my app. If you want to reach out to me on Discord and GitHub it's mintami and on Instagram if you want to follow along with my art journey it's marit. Thank you very much.