Projects Portfolio
15 projects

This mobile app allows motorists to give gratuities to the informal car guards that are ubiquitous in South Africa.
Car guards are individuals who provide an informal parking attendant service. They are typically dressed in high-visibility vests and assist motorists in finding parking spaces, keeping an eye on vehicles while the owner is away, and sometimes helping drivers maneuver out of tight spots. Although car guards are not officially regulated or employed by the parking facilities or retail establishments they frequent, their presence is a well-known aspect of urban life in South Africa.
This mobile application leverages modern web technologies and delivers a seamless user experience akin to native store apps. It can be installed directly onto devices and offers offline functionality, employing Progressive Web Applications (PWA) technology for caching capabilities that mitigate the dependence on an internet connection.
Upon completing a registration process within the app, car guards initiate their monitoring service by photographing vehicles enrolled in the program, identifiable through a designated sticker, which serves as verification of their oversight. They are prompted every 15 minutes with a push notification to capture successive images, ensuring continuous supervision. The guards' interface displays these photographs sequentially, arranged based on the required timing for the subsequent snapshot. [...more]
Car guards are individuals who provide an informal parking attendant service. They are typically dressed in high-visibility vests and assist motorists in finding parking spaces, keeping an eye on vehicles while the owner is away, and sometimes helping drivers maneuver out of tight spots. Although car guards are not officially regulated or employed by the parking facilities or retail establishments they frequent, their presence is a well-known aspect of urban life in South Africa.
This mobile application leverages modern web technologies and delivers a seamless user experience akin to native store apps. It can be installed directly onto devices and offers offline functionality, employing Progressive Web Applications (PWA) technology for caching capabilities that mitigate the dependence on an internet connection.
Upon completing a registration process within the app, car guards initiate their monitoring service by photographing vehicles enrolled in the program, identifiable through a designated sticker, which serves as verification of their oversight. They are prompted every 15 minutes with a push notification to capture successive images, ensuring continuous supervision. The guards' interface displays these photographs sequentially, arranged based on the required timing for the subsequent snapshot. [...more]
Keywords:
typescript, javascript, docker, nodejs, cloudflare workers, fly.io, svelte, geolocation, sveltekit, SQL, Supabase, Tailwindcss
typescript, javascript, docker, nodejs, cloudflare workers, fly.io, svelte, geolocation, sveltekit, SQL, Supabase, Tailwindcss



This is a large-scale software-as-a-service (SaaS) application for customer service chats.
The application is designed to be efficient and cost-effective and support tens of thousands of users concurrently.
This is a chat system that allows website visitors to ask questions to human chat agents. Although artificial intelligence is improving, many organizations and visitors alike prefer human answers. Humans are better at understanding complex questions and providing nuanced answers. They are also better at building rapport and trust with customers.
This chat app was made with businesses and organizations in mind that want to provide top-notch customer service. It recognizes the importance of human interaction in resolving customer issues. It can be used in a variety of industries, including e-commerce, corporate, marketing and sales, education, nonprofits, and NGOs. The chat app is also highly optimized for outsourced customer service organizations. These organizations typically have a large customer base and manage chat operations on their behalf. The administrative side of the app is designed to make it easy to add new customers and their websites and domains.
Overall, this app is a comprehensive, user-friendly live chat solution that helps businesses provide superior customer engagement and service. It seamlessly blends technology with the irreplaceable human touch, ensuring that customer issues are resolved quickly and efficiently.
The app is fast, but speed was not the primary focus of the design. The main goal was to keep resource usage low so that pricing for users could be kept as low as possible. This is important because the app is used by a large number of people, and the cost of running the app can be significant. This low resource usage is achieved by using efficient technologies and hosting providers and by giving agents the tools to handle as many chats in the shortest time possible. In the context of this type of chat app, speed is not as important as it may seem. This is because website visitors are often slow typists, and agents are often handling dozens of chats at the same time. This means that there will always be some waiting time, regardless of how fast the app is. [...more]
I was responsible for the entire development process of this application, from gathering requirements to writing the code. I understood the needs of the users, designed the architecture of the application, and implemented the code. I also tested the application to ensure that it worked correctly. I'm proud of this app because it showcases my coding skills and ability to build applications.
This is a chat system that allows website visitors to ask questions to human chat agents. Although artificial intelligence is improving, many organizations and visitors alike prefer human answers. Humans are better at understanding complex questions and providing nuanced answers. They are also better at building rapport and trust with customers.
This chat app was made with businesses and organizations in mind that want to provide top-notch customer service. It recognizes the importance of human interaction in resolving customer issues. It can be used in a variety of industries, including e-commerce, corporate, marketing and sales, education, nonprofits, and NGOs. The chat app is also highly optimized for outsourced customer service organizations. These organizations typically have a large customer base and manage chat operations on their behalf. The administrative side of the app is designed to make it easy to add new customers and their websites and domains.
Overall, this app is a comprehensive, user-friendly live chat solution that helps businesses provide superior customer engagement and service. It seamlessly blends technology with the irreplaceable human touch, ensuring that customer issues are resolved quickly and efficiently.
The app is fast, but speed was not the primary focus of the design. The main goal was to keep resource usage low so that pricing for users could be kept as low as possible. This is important because the app is used by a large number of people, and the cost of running the app can be significant. This low resource usage is achieved by using efficient technologies and hosting providers and by giving agents the tools to handle as many chats in the shortest time possible. In the context of this type of chat app, speed is not as important as it may seem. This is because website visitors are often slow typists, and agents are often handling dozens of chats at the same time. This means that there will always be some waiting time, regardless of how fast the app is. [...more]
Keywords:
websockets, javascript, docker, nodejs, redis, supabase, jsonwebtokens, cloudflare workers, fly.io, svelte, sveltekit, Supabase, Typescript, Tailwindcss
websockets, javascript, docker, nodejs, redis, supabase, jsonwebtokens, cloudflare workers, fly.io, svelte, sveltekit, Supabase, Typescript, Tailwindcss

Temperature and humidity have an impact on your physical performance. When exercising in hot conditions, your body has to work harder to regulate its temperature, which can lead to increased heart rate and sweat production. This can make workouts feel more challenging and tiring.
As you can see in the image left and right of the laps counter, the temperature was over 30 degrees Celsius and the humidity was almost 80% (I live in South East Asia). The temperature and specially the humidity differs from day to day and between early mornings and afternoons. So adding this information to the app and to the AWS Dynamo database is a good way to analyze how big of an influence this has on my performance.
See below or here and here for earlier descriptions of this app and the hardware used.
To get the temperature and humidity data I used a $2.50 SHT30 sensor and connected that to the hardware described here .
Backend:
All data from every walk is sent to an AWS lambda (via a function link, no Gateway API is used) that does some formatting and then stores it in a DynamoDB database for retrieval in a front end that I still have to write. [...more]
As you can see in the image left and right of the laps counter, the temperature was over 30 degrees Celsius and the humidity was almost 80% (I live in South East Asia). The temperature and specially the humidity differs from day to day and between early mornings and afternoons. So adding this information to the app and to the AWS Dynamo database is a good way to analyze how big of an influence this has on my performance.
See below or here and here for earlier descriptions of this app and the hardware used.
To get the temperature and humidity data I used a $2.50 SHT30 sensor and connected that to the hardware described here .
Backend:
All data from every walk is sent to an AWS lambda (via a function link, no Gateway API is used) that does some formatting and then stores it in a DynamoDB database for retrieval in a front end that I still have to write. [...more]
Keywords:
Typescript, Javascript, Nodejs, Websockets, ESP8266, SHT30, C++, AWS CDK, DynamoDB, Lambda, Serverless
Typescript, Javascript, Nodejs, Websockets, ESP8266, SHT30, C++, AWS CDK, DynamoDB, Lambda, Serverless
The first app (see below) wasn’t comfortable to use. While walking your mind wanders off and it is difficult to remember to press the lap button each time.
So I had to find a different solution. I wanted to have something that would automatically add a lap when you passed a certain point.
For this I used a microcontroller unit, a very small computer specialized in handling input and output sensors. The board I used is a D1 mini with an ESP8266 chip that has WiFi and Bluetooth. I combined the D1 with an infrared motion detector (PIR) and a small beeper. The whole setup cost less than $5.
This works wonderfully well. The first time I pass the motion sensor it will start the timer and every next pass it will add a lap time and send that to the node js app. I can start and stop with the web app on my phone.
Backend:
Backend setup with AWS CDK: Leveraging AWS skills, the app utilizes AWS CDK to quickly set up a backend, including a DynamoDB table and two Lambdas. One Lambda is responsible for storing data, while the other retrieves the saved information. [...more]
So I had to find a different solution. I wanted to have something that would automatically add a lap when you passed a certain point.
For this I used a microcontroller unit, a very small computer specialized in handling input and output sensors. The board I used is a D1 mini with an ESP8266 chip that has WiFi and Bluetooth. I combined the D1 with an infrared motion detector (PIR) and a small beeper. The whole setup cost less than $5.
This works wonderfully well. The first time I pass the motion sensor it will start the timer and every next pass it will add a lap time and send that to the node js app. I can start and stop with the web app on my phone.
Backend:
Backend setup with AWS CDK: Leveraging AWS skills, the app utilizes AWS CDK to quickly set up a backend, including a DynamoDB table and two Lambdas. One Lambda is responsible for storing data, while the other retrieves the saved information. [...more]
Keywords:
Typescript, Javascript, Nodejs, Websockets, ESP8266, C++, AWS CDK, DynamoDB, Lambda, Serverless
Typescript, Javascript, Nodejs, Websockets, ESP8266, C++, AWS CDK, DynamoDB, Lambda, Serverless
The Walking App was developed to address the limitations of fitness features on the Apple Watch for individuals with specific health conditions, such as C.O.P.D. This app allows users to track their walks in terms of pace and distance, catering specifically to indoor walking where the Apple Watch cannot accurately measure these metrics. The goal of the app is to provide a tool for individuals who need to exercise within certain limitations and effectively monitor their fitness goals.
Key Features:
Accurate tracking: The Walking App accurately measures the user's pace and distance during walks, providing precise data to track their progress or regression over time.
Indoor walking support: Unlike the Apple Watch, which primarily focuses on outdoor activities, this app is designed to track indoor walks, making it suitable for those who prefer or need to walk indoors.
Backend setup with AWS CDK: Leveraging AWS skills, the app utilizes AWS CDK to quickly set up a backend, including a DynamoDB table and two Lambdas. One Lambda is responsible for storing data, while the other retrieves the saved information. [...more]
Key Features:
Accurate tracking: The Walking App accurately measures the user's pace and distance during walks, providing precise data to track their progress or regression over time.
Indoor walking support: Unlike the Apple Watch, which primarily focuses on outdoor activities, this app is designed to track indoor walks, making it suitable for those who prefer or need to walk indoors.
Backend setup with AWS CDK: Leveraging AWS skills, the app utilizes AWS CDK to quickly set up a backend, including a DynamoDB table and two Lambdas. One Lambda is responsible for storing data, while the other retrieves the saved information. [...more]
Keywords:
Typescript, AWS CDK, DynamoDB, Lambda, Svelte, Svelte Native, Nativescript, Serverless
Typescript, AWS CDK, DynamoDB, Lambda, Svelte, Svelte Native, Nativescript, Serverless

A small proof of concept to run Apollo GraphQL servers on Cloudflare workers. Copilottravel.com, a startup that is building the next generation travel search and booking engine, asked me to
make a small example on how to run
Apollo GraphQL
servers on Cloudflare workers. For their travel search engine they need combined data from dozens
of different sources. GraphQL was made for these kinds of applications.
My work gave them a handle to continue their porting efforts from Google Cloud to Cloudflare. [...more]
My work gave them a handle to continue their porting efforts from Google Cloud to Cloudflare. [...more]
Keywords:
Javascript, Apollo Server, Apollo Gateway, Cloudflare Workers, Serverless
Javascript, Apollo Server, Apollo Gateway, Cloudflare Workers, Serverless

A simple website built in a day with Sveltekit and Tailwind running on Cloudflare's workers.
Normally I don't do very plain websites but I did this for my brother and I wanted to play around with Sveltekit and Cloudflare Workers. So while this is a simple website from an HTML prespective, there are also complicated technologies involved. It's a serverless app running on Cloudflare's edge network. This means it's infinitely scalable, super secure, very fast for visitors where it doesn't matter if you are in Alaska or Zimbabwe and - in case of Cloudflare - can be deployed with a single command. (Actually, with the latest version of Cloudflare Workers/Pages, you only need to push it to a repository like Github or Gitlab)
You can see the result at rep-it.nl. This was my first attempt to build something with Sveltekit, a new web framework with a radically different approach than most other web frameworks. Svelte is a component framework — like React or Vue — but with an important difference.
Traditional frameworks allow you to write declarative state-driven code, but there's a penalty: the browser must do extra work to convert those declarative structures into DOM operations, using techniques like that eat into your frame budget and tax the garbage collector. Sveltekit can generate different types of websites, static and server side rendered and uses adapters to tailor the result to specific deployment types like Cloudflare Workers, Node.js, Netlify, Vercel, etc.
In this case I used Cloudflare Workers. For styling I tried Tailwind, something I wanted to work with for a long time. With very little effort I got a perfect score on Google’s Lighthouse, a website performance toolkit, both on Desktop and Mobile. [...more]
Normally I don't do very plain websites but I did this for my brother and I wanted to play around with Sveltekit and Cloudflare Workers. So while this is a simple website from an HTML prespective, there are also complicated technologies involved. It's a serverless app running on Cloudflare's edge network. This means it's infinitely scalable, super secure, very fast for visitors where it doesn't matter if you are in Alaska or Zimbabwe and - in case of Cloudflare - can be deployed with a single command. (Actually, with the latest version of Cloudflare Workers/Pages, you only need to push it to a repository like Github or Gitlab)
You can see the result at rep-it.nl. This was my first attempt to build something with Sveltekit, a new web framework with a radically different approach than most other web frameworks. Svelte is a component framework — like React or Vue — but with an important difference.
Traditional frameworks allow you to write declarative state-driven code, but there's a penalty: the browser must do extra work to convert those declarative structures into DOM operations, using techniques like that eat into your frame budget and tax the garbage collector. Sveltekit can generate different types of websites, static and server side rendered and uses adapters to tailor the result to specific deployment types like Cloudflare Workers, Node.js, Netlify, Vercel, etc.
In this case I used Cloudflare Workers. For styling I tried Tailwind, something I wanted to work with for a long time. With very little effort I got a perfect score on Google’s Lighthouse, a website performance toolkit, both on Desktop and Mobile. [...more]
Keywords:
Javascript, HTML, CSS, Tailwind, Svelte, Sveltekit, Cloudflare Workers, Responsive Layout, Server-Side-Rendering, Serverless
Javascript, HTML, CSS, Tailwind, Svelte, Sveltekit, Cloudflare Workers, Responsive Layout, Server-Side-Rendering, Serverless

This website. Built with Sveltekit and Tailwind running on Cloudflare's workers.
Because LinkedIn does not offer a nice way to show a projects portfolio, I built this website.
I wanted to show every page as a separate link on my profile so I needed a Server-Side-Rendered website.
I also wanted to use Serverless hosting so I don't have to pay for a full server running 24x7. Sveltekit, together with the Cloudflare adapter makes this just a deployment option without the need of any code changes.
The Tailwind CSS utility classes made it possible to not have a css file or create classes on every page. Instead you can do a sort of real-time design; keep a browser window open next to your editor and add utility classes directly on elements, like font-bold, text-gray-500 or mt-5 for a top margin.
I like to keep two browser windows open next to my editor; one for a mobile view and one for a desktop view. This way I can immediately see if I need different classes/layouts for mobile or desktop. This way of working is very efficient and a real time saver. [...more]
I also wanted to use Serverless hosting so I don't have to pay for a full server running 24x7. Sveltekit, together with the Cloudflare adapter makes this just a deployment option without the need of any code changes.
The Tailwind CSS utility classes made it possible to not have a css file or create classes on every page. Instead you can do a sort of real-time design; keep a browser window open next to your editor and add utility classes directly on elements, like font-bold, text-gray-500 or mt-5 for a top margin.
I like to keep two browser windows open next to my editor; one for a mobile view and one for a desktop view. This way I can immediately see if I need different classes/layouts for mobile or desktop. This way of working is very efficient and a real time saver. [...more]
Keywords:
Javascript, HTML, CSS, Tailwind, Svelte, Sveltekit, Cloudflare Workers, Responsive Layout, Server-Side-Rendering, Serverless
Javascript, HTML, CSS, Tailwind, Svelte, Sveltekit, Cloudflare Workers, Responsive Layout, Server-Side-Rendering, Serverless

I came across this project on one of the freelance IT-projects websites. Because, for obvious reasons, I cannot share that much on projects I did for customers, so I decided to spend a week and build part of this app to show what I can do, how it would look like and how much I can archive in a week's time. You can see it working at crm.naguras.com. The specs document is at my Google Drive.
This project is a good example of how I translate business requirements in an application. After reading the specifications I still had a lot of questions but also enough to build something functional. [...more]
This project is a good example of how I translate business requirements in an application. After reading the specifications I still had a lot of questions but also enough to build something functional. [...more]
Keywords:
Javascript, Node.js, Express.js, MongoDb, Vue.js 3, Quasar Framework, AWS EC2, AWS S3 Web Server, JSON Web Tokens, Docker, Docker Compose, NGINX, Let’sEncrypt, HTTPS, SSL, HTML, CSS, Responsive Layout
Javascript, Node.js, Express.js, MongoDb, Vue.js 3, Quasar Framework, AWS EC2, AWS S3 Web Server, JSON Web Tokens, Docker, Docker Compose, NGINX, Let’sEncrypt, HTTPS, SSL, HTML, CSS, Responsive Layout

musicaltheatersongs.com
is a web application for musicians and users in the musical and theater sector to search for
musical songs based on musical-technical terms. The app is mainly used by musical students and
teachers. It contains more than 11,000 songs and is used by tens of thousands of users globally.
The original app was written more than 6 years ago and used a MVC framework called Derby which
became obsolete. It was difficult to maintain the code or to add new functionality. I was asked
to rewrite the application using a more modern toolset.
The original application had two functional parts (actually three if you count the Mongodb database as a part of the application) but was built as a single app (except for the database which is a separate service). The two functional parts are the website front-end, the part end users see and use for their searches and store their songs lists. The other part is an admin section where new songs, shows, composers and lyricists are entered and modified. It also manages user’s subscriptions, both individual and institutional (universities, etc). [...more]
The original application had two functional parts (actually three if you count the Mongodb database as a part of the application) but was built as a single app (except for the database which is a separate service). The two functional parts are the website front-end, the part end users see and use for their searches and store their songs lists. The other part is an admin section where new songs, shows, composers and lyricists are entered and modified. It also manages user’s subscriptions, both individual and institutional (universities, etc). [...more]
Keywords:
Javascript, HTML, CSS, Node.js, Express.js, MongoDb, Vue.js 2, Vue.js 3, Quasar Framework, Mocha Unit Test Framework, Cypress Integration Test Framework, PM2 Process Manager, AWS EC2, AWS S3 Web Server, AWS Lambda, AWS SQS Messages, AWS Parameter Store, Nodemailer, Stripe Payment API, Websockets, AWS Cloud Development Kit, AWS CloudFront, AWS Event Bus, JSON Web Tokens, Docker, Docker Compose, NGINX, Let’sEncrypt, HTTPS, SSL, Responsive Layout, Server-Side-Rendering, Serverless, Linux shell scripts
Javascript, HTML, CSS, Node.js, Express.js, MongoDb, Vue.js 2, Vue.js 3, Quasar Framework, Mocha Unit Test Framework, Cypress Integration Test Framework, PM2 Process Manager, AWS EC2, AWS S3 Web Server, AWS Lambda, AWS SQS Messages, AWS Parameter Store, Nodemailer, Stripe Payment API, Websockets, AWS Cloud Development Kit, AWS CloudFront, AWS Event Bus, JSON Web Tokens, Docker, Docker Compose, NGINX, Let’sEncrypt, HTTPS, SSL, Responsive Layout, Server-Side-Rendering, Serverless, Linux shell scripts

I was asked to help with a Bitcoin clone (fork) called Bitcoin Euro (BTE). I installed a number of BTE nodes on virtual servers and set up the necessary infrastructure around it like a blockchain explorer, a mining pool and a wallet. For this I adapted a few Open Source projects to work with BTE instead of Bitcoin. I’m not really a blockchain expert but I do have a reasonably good insight in how blockchains work. I did make some small changes to the Bitcoin source code (made with c++). The explorer, mining pool and wallet software were all built with Javascript technologies and node.js. [...more]
Keywords:
Javascript, HTML, CSS, Node.js, Express.js, MongoDb, c++
Javascript, HTML, CSS, Node.js, Express.js, MongoDb, c++

The Cloud Trade Copier is a cloud based Binary Options Trading System system where Signal Providers send signals to the service using a web based interface. When a signal arrives, all the subscribers to that signal are gathered from a Redis in-memory key-value store. Per user we check which broker they use and send the signal to other microservices (one or more per broker) that will send the purchase transaction to the broker's server. [...more]
Keywords:
Javascript, HTML, CSS, Node.js, Express.js, MongoDb, AWS EC2, AWS S3 Web Server, Redis, Websockets, Vue.js, Bootstrap CSS, queues, micro-services, JSON Web Tokens, Docker, PM2, Jelastic, Winston logging and Loggly logging
Javascript, HTML, CSS, Node.js, Express.js, MongoDb, AWS EC2, AWS S3 Web Server, Redis, Websockets, Vue.js, Bootstrap CSS, queues, micro-services, JSON Web Tokens, Docker, PM2, Jelastic, Winston logging and Loggly logging

This is a Desktop app for Windows and Mac that can trade Binary Options based on signals from a Signal Provider. The signal provider uses a simple app as pictured below to signal a trade opportunity. Because the binary options trade is a very fast moving business where a single second can mean the difference between a losing or winning trade, the interface has to be really simple so with just a single click the trader (the person generating the signal) can send out the signal. [...more]
Keywords:
Electron, HTML, CSS, Node.js, jQuery, Express.js, AWS EC2, MongoDb, JSON Web Tokens, Docker, Pusher, Winston logging and Loggly logging
Electron, HTML, CSS, Node.js, jQuery, Express.js, AWS EC2, MongoDb, JSON Web Tokens, Docker, Pusher, Winston logging and Loggly logging

The end-users who subscribe to one or more signal providers use another Desktop app for Windows or Macintosh to trade the signals the provider sends out. The Binary Option Brokers do not give API access to their trading systems. So I built an app that will open a broker’s website and inject some Javascript code in the webpage to be able to control the website and execute trades. [...more]
Keywords:
Electron, HTML, CSS, Node.js, jQuery, Express.js, MongoDb, AWS EC2, AWS S3 Web Server, JSON Web Tokens, Docker, Pusher, Winston logging and Loggly logging
Electron, HTML, CSS, Node.js, jQuery, Express.js, MongoDb, AWS EC2, AWS S3 Web Server, JSON Web Tokens, Docker, Pusher, Winston logging and Loggly logging

A shrink wrapped Windows Desktop program for bookkeeping created for the Dutch market. I did the design, architecture and programming of this app. At it's time it was a refreshing new approach to accounting and got thousands of users. The goal was to make it as easy as possible for non specialists to keep their books up-to-date. [...more]
Keywords:
C#, Dot-net, DevExpress UI components, SQL Server, Azure, ASP.net, XML, SOAP, PKI
C#, Dot-net, DevExpress UI components, SQL Server, Azure, ASP.net, XML, SOAP, PKI