The web application is called TopPerformanceNow and is built for a client who provides employee sourcing, training and developing services. You can find his page here (disclaimer: not built by me). I opted to go with Visual Studio 2013, though this app is likely the last I am going to build in VS2013. VS2015 has way better tooling and a plethora of front-end productivity improvements.
I always like to start with an Empty template and import the libraries I need via Nuget. Since this app is rather small in scope, I used Nuget to get KnockoutJS, jQuery, momentJS and pagerJS and just kept them in the Scripts folder. I kept the CSS (or in this case LESS) in the Content folder. Generally, I try to split all that stuff into its own App folder (and VS2015 does this with a wwwroot folder by default in the new project templates).
I chose to go with LESS. There’s no reason, really. I use SASS at work. I know some purists will rage when I say “they’re the same”, but I really don’t see any differences in my workflow. Functions, mixins, variables, nesting… both languages have it.
I split my LESS up into several modules: _Colors, _Forms, _Icons, _Typeface, _Reset, and individual page partials which all converged on App.less. These are all pretty self-explanatory, though one thing to mention is that _Icons contains the CSS I get back from icomoon that holds the icon styles. More on that next!
Personal preference, but rather than grabbing the whole font, I like to pick and choose which icons I really need and building a font out of them. Icomoon is great for that! They have some in-house icons, but you can also import fonts from tons of other libraries including everybody’s favorite FontAwesome (which I used in this app). I highly recommend checking out Icomoon if you’re looking for icons for your app. Make sure to check what kind of license each one has though.
I used Knockout with pagerJS, which I found to be much more intuitive than Sammy. I used Sammy on my first KO project ever and I recall it was a huge chore. Pager is straight up just 3 lines of code to get working and all the routes are automatically wired up via bindings in the HTML. It’s magic, and it’s simple. Pager also allows you to use HTML5 history (not sure if Sammy does?) though it takes some guessing to get wired up, because the documentation on that is awful.
I didn’t build out a Web API infrastructure for this app, because I really only need one JSON controller and I didn’t want to add the Web API libraries just for a few methods. MVC can accomplish the same with JsonResult.
One mistake I made was not using the Role provider that comes with SimpleMembership to sort people into Trial, Normal and Admin. I store people’s state in the database in the form of an enumerator. It works, but thinking back on it, using Roles would probably have been more consistent. You’ll notice that I opted to skip the ASP.NET Identity stack here. As I wrote in my previous post
I have a few models and enums for holding data. I also built out 3 repositories for handling data access. In this application, the repository pattern was a no-brainer since it’s all CRUD.
Lastly, there’s a document processor class with 4 methods which each process the data I get from the database and turn it into document files.
I store all data in SQL, but I am pretty conservative with how I use the space. Previous developer who built the app 15 years ago stored individual fields as marked records (like, 28a, 14b) so each app user who had 2 forms per position and 40 fields per form had 80 table records per position. With average of 6 positions per user, that’s 480 records per user, and there are hundreds of users.
I opted to go a different route. Forms are stored as JSON blobs. Now a user can have 6 positions – that’s 6 position records, and each position has only 2 records in the Forms table attached. Forms are stored as a string in a Key:Value pair format. Keys correspond to form field names, so when parsing the forms in the middle tier either for retrieval or document generation, they’re trivially easy to process. This also gives me an opportunity to reuse code in both instances.
The page is hosted on Microsoft Azure’s Shared hosting plan and the data is stored in Azure SQL. Perhaps I’m a bit biased (I love Azure), but after my experience with mass shared hosting (GoDaddy) I’d rather stay away. The cost for the above is right about $15/month and it comes with the peace of mind you don’t get with GoDaddy.
This app took me just about 90 hours to build from start to finish. Granted it’s not very complicated, it allowed me to apply all I’ve learned to building out a solid web application from the ground up. I already have another project I’m working on now. This one is going to require the module/controller approach in the front-end. I’ve already created the solution for it in VS2015 and followed a pretty specific and rather different process than above. Perhaps a story for another blog post…