Have I switched to Tailwind?

I’ve never been much of a designer; I know what I like and I can recreate any design a designer passes my way. However, producing anything original is incredibly hard.

I switched to Bootstrap many years ago to help me solve the problem, Bootstrap made it easy to create what I wanted and still have it look OK – typically more than ok.

Bootstrap sites typically look the same and before I go on, I don’t necessarily consider that a “bad thing”. The problem arises when you don’t want everything to look the same. Customisation is possible with Bootstrap, particularly version 5. However, it gets complicated quickly.

I’ve released three Apps in the last year, two game scorers for Yahtzee and Yatzy and Budget, a free open-source budgeting App. The Apps all look ‘similar’, this isn’t necessary a problem because they all belong to the Costs to Expect service so it should be obvious that they belong to the same brand. However, I wanted something different for Budget Pro, an evolution of Budget.

Budget Pro belongs to the same family as all the Apps I released this year but being the paid version, I wanted to differentiate it from Budget and give it a sharpened look. Due to its features, it will also have a more complex UI than Budget. As I was thinking about how to ‘improve’ the Budget design I decided to give Tailwind a go as everything I’ve seen of it has impressed me, particularly Tailwind UI.

Two things pushed me over the edge. Firstly. Tailwind UI, having an extensive library of components to build with and from made it easy to get started and start building up ideas. Secondly, the standalone cli; I don’t want or need any additional dependencies and prefer vanilla JavaScript over any front-end toolchains.

I’m only a little way into my journey with Tailwind but so far, I’m loving it. Yes, you end up with lots of classes in the HTML. However, you know what each of them do based on the name and I create components to reduce duplication anyway.

We’ll see if the honeymoon continues as I move away from landing and content pages and get into the nitty gritty of creating the meat of Budget Pro.

Invokable controllers

For several years I have been a fan of invokable classes, typically to act as action classes for forms and to create jobs for queues etc.

With regards to forms, this works well. The validation and creation code is all contained in one class keeping code out of the controller. If all you need is validation and a little logic before saving/updating, this model works well. The model breaks down when the complexity goes up.

On a recent project, I needed to validate the request, convert the data, generate lots of additional values related to fluid flow and validate again. Only after I have calculated the viability of the submitted data, do I save the request.

My action classes have simple names – createGame, saveUser, – you get the idea. From reading the name of the action, you know what it does and when you look inside, you have an idea about what you will see. This doesn’t work when there are five or six steps that must happen before the “quote” is created.

Invokable controllers to the rescue – I get all benefits of invokable action classes without the negative of a giant action class which is doing more than its name suggests.

I rarely use invokable controllers but when I do, they are a life saver.

Supporting multiple measurement units

I’m working on a freelance project in which there are multiple measurement units. For example, customers can provide their required flow rate in litres per second, litres per minute, litres per hour, cubic meters per hour, gallons a minute or imperial gallons per minute.

Warning: This gets really complicated, fast!

You might have noticed we have imperial and metric measurement units above. Well, that means we need to support mm, meters, degrees Celsius and the inferior imperial versions some people still use. You know who you are.

To try and keep it simple, I have ingress objects which take all values and convert them to a ‘known’ unit of measurement for each type. I can then process all my calculations and not need to be concerned with converting anything whilst I’m calculating. When done, I have egress objects which convert everything back to the required unit and format.

I’m also storing everything in the original format, and I’ve tended to find over the years that this is better than converting and then storing. Customers don’t tend to like it when a value of three returns as 2.99997 next time they look at the request.

I’m only a little way into the project but so far, having a single interface to deal with is making much easier as I only need to care about the units for a value at the time it enters the ‘service’ and the moment it exits the ‘service’ and is about to be presented on screen.

Hopefully, all goes well, only time will tell.

Blog posts on freelance projects are deliberately a little vague as I can’t really divulge too much, I can talk about general stuff but obviously I’m never going to mention specifics.

1000km

I started running at forty-two and on telling my wife about my new soon-to-be obsession, she laughed at me! Seemingly, the idea of me running was funny but my wife should have known better.

The first two years did not go well. I ran around 200km each year, wasn’t very consistent and even though I got a little faster and hit some self-set milestones, I didn’t feel like a runner.

This year came a change of mindset and I decided to become a runner. (In my head anyway, everyone that runs is a runner.) I ordered a new watch (Garmin 945 – thank you wife) and decided to start taking things more seriously. I was going to up my mileage and follow all the advice – run easy, build up gradually, warm up, you know the drill.

I decided I needed a goal, so I set myself a goal that was challenging and yet seemed achievable. I was aiming to run a total of 400km in 2022 so doubling my mileage of the last couple of years.

I did not follow all the advice, none of us do. Slow easy running does help but I’m terrible for wanting to always hit a new personal best.

As of today, I’ve run 1067km so I’m well on target to triple the goal I set for myself at the start of year. I’ve taken 6 minutes of my 5km time, hitting 24 minutes and got my 10km time down to 52 minutes. The impressive part, to me at least, is that neither of those times are race times, they were set during training, and both started off easy. I’ve no idea what my go for broke times are.

I’m forty-six next year and before I get there, I’d like to get my 5km time down to 21 minutes and my 10km time down to sub 48 minutes. Both targets seem achievable and according to my watch I’d be able to hit those times today given perfect race conditions, so we’ll see, I guess.

Next year I don’t think I will be able to reach the same mileage. I’ve been freelancing this year and am free to run when I choose to as I can do my work any time of day. I’ll be contracting next year so it will be slightly more difficult to fit the runs in.

I’m aiming to enter two ultramarathons next year, both 50km. That’s a new challenge and I’m really looking forward to them. It’ll be a big step up for me as the longest single run I have done so far is 20km.

Returning to Costs to Expect, finally!

My own projects have taken a back seat whilst I’ve been busy working on a freelance project which scaled well beyond the initial scope, that project is almost over and I suspect I’m going to be free for a little while to work on my own projects again. I can start pushing towards the soft release of the Costs to Expect API and App.

The API

The API has been feature ready for a while, its issues are unnecessary complexity. When I started adding new “item-types” I opted for a little too much abstraction. I’ve been designing the budgeting system (on paper) for a while, it is not going to work in the same way as the existing “item-types” so I’ve been busy removing all the abstractions and in general refactoring the shit out of the API.

I didn’t look at the API code for a year, that time gave me a fresh perspective, I’m simplifying the majority of the “item-type” code, there is no need for everything to extend from a base class if there is going to very little overlap in functionality.

In addition to the refactoring I’m moving our tests local, rather than relying on a Postman collection I’m moving all the tests to PHPUnit. I can replicate every test in the Postman collection locally as well as test things that could never be caught by only looking at responses. I expect I will keep the Postman collection around because there are tests that a simpler to do with it but having everything local is going to be a major benefit and of course necessary for the official release.

I have 11 stories left in my tracker, the API will then hit our soft release milestone. This milestone has been a long time coming, I still can’t quite believe we are this close.

The App

The App needs more work, there are 24 stores in my tracker, my wife and I are yet to pick the App apart, so, more stories will get added. App development tasks are simpler, the API does the heavy lifting, the majority of the work on the App is presentation.

The App is closed source, the API is open source, we handle each slightly differently, with the App we are focused on the features and not so much the overall design, assuming it works, with the API, the design takes a front seat as it has to potentially be maintainable by more than just us. The reality is, I develop everything so I’m not really switching styles, we just might approach the backlog in a different way.

Official release

Once the App and API both hit their soft release milestones, I’ll cry, no really, this has been such a long time coming, I’ve been planning the budgeting and forecasting system, forever.

There might be a slight detour whilst I develop another App rather than get on with the Budgeting and Forecasting. As mad as that sounds given how long it has taken to get here, it can be thought of as an experiment/proof of concept. The budgeting and forecasting will not behave as per anything else in the App so I need to test the API and my front-end skills.

The next four months are going to be full-on, all we can do is see where we are in September and go from there.