>>> 1) I have a bunch of projects, but they're terribly boring and have ugly looking code. For example, I spent a year working on an ecommerce site. It does what it needs to do, but there were no smart decisions behind the back end. I never had to use design patterns nor data structures. I just pieced it together.
This is not optimal. At the very least having knowledge of usual data structures and some common design patterns is kind of a requirement to get any decent development job. But I think you might actually know more about data structures/patterns than you think.
When working on the ecommerce site, you must have had come across some of these. Let's say the site was written in a high level language. For sure you have used/seen classes, array (or some higher level wrapper like lists in Python or slices in Go), hash maps. When fetching products to be displayed in the "storefront" part of the site, you might have used array/list/slice to store these.
I assume the ecommerce site used database to store data. So perhaps there was singleton pattern used to get a database connection (although this one is not the best example). What about dependency injection? How was configuration passed to objects?
Did some classes inherit from other classes? Did you see interfaces? E.g. a classic example is a payment method interface and then specific implementations for different payment methods (card, direct debit). If there are interfaces it's quite likely you will find a factory to get instance of a specific object implementing the interface?
Have you done any frontend work in JavaScript? If yes, you must be familiar with event listeners. There's a good example of observer pattern for you (queue where you register listeners for specific events) which is very important for event driven programming.
>>> 2) I have a lot of trouble with "HackerRank" style problems. I just finished one, an hour ago, called Codility. Even though I passed all the shown test cases, the final results showed that I got the following scores 13%/95%/0%. The 0% was a debugging problem that required a max of 2 line changes. I have absolutely no clue how I got a 0% there.
Try more of these courses, with practice you will get better. It's very likely you have missed something very obvious with the problem where you got 0% although you thought you got it right. Perhaps you haven't tried it with all example input values?
--------------
Anyways, I would start by taking small steps. Whatever job you currently have, try to become a better programmer by using new or better techniques while in your 9-5 job. Perhaps refactor some old part of codebase and use more effective data structures to make the code more efficient. Use objects and composition to make the code easier to read and understand. When working on a new feature, write unit tests alongside the code.
Also, when it comes to interviewing, you will also get better at it with experience. I have had quite a lot interviews in my career and I can definitely say I was pretty bad at interviewing 7 years ago. Today I am noticeably better and do very well in most interviews and whiteboard exercises.
Do an online exercise or two, study up on data structures and patterns, maybe create some small project to keep some fresh programming footprint in memory. Then go try more interviews, you'll do much better.