Projects
- Angular
Imalo Education Website
Imalo is a German-language afterschool program for children in Sibiu, Romania. Its website is where parents first meet it: what the program offers, the daily schedule, a photo gallery and a way to get in touch. Everything is available in both Romanian and German.
Features
- Two languages: every page switches between Romanian and German with one toggle.
- Photo gallery: a full-screen gallery of life at Imalo, navigable with the mouse or the keyboard.
- Contact form: questions from parents go straight to Imalo's inbox.
Use case
A parent finds Imalo online, reads about the program in German and sends a question through the contact form.
How it's built
Built with Angular 22 using standalone components, zoneless change detection and Signals, with every page prerendered through SSR for speed and SEO and hosted on Firebase. Each route is lazy-loaded, and page changes use the browser's View Transitions for a smooth feel. The Romanian/German switch is a small signal-based language service rather than a full i18n library, which suits a site with two languages. The gallery is a custom lightbox driven by the mouse or keyboard, animated with Angular's native enter and leave bindings instead of the animations package. The contact form sends emails straight from the browser through EmailJS, with no backend of its own. Unit tests run on Vitest and cover the language, SEO and email services, the form validation and the gallery navigation.
- Angular
- .NET
Imalo Education Webapp
The staff side of Imalo: a web app that keeps track of every child in the afterschool program. It records who picks each child up and when, which days they came, and what lunch and transport cost. Everything the team needs to know about a child is in one place.
Features
- Dashboard: the day at a glance: key numbers, today's pick-ups, upcoming birthdays and recent activity.
- Scholar records: school, class, gender, birth date, parents and phone numbers, in a searchable, sortable list that exports to CSV.
- Pick-up timeline: every child's weekly pick-up times in 15-minute slots, colored by school, so busy moments are visible in advance.
- Attendance and costs: a monthly grid for all children and an editable month per child, recording presence, lunch and transport along with their cost.
- Charts: hand-built charts, with no chart library, of children by school, class and gender, attendance trends and monthly costs.
- Audit log and safeguards: a history of every change, per child and overall, a warning before leaving a form with unsaved changes, and a banner if the API goes down.
Use case
When a child enrols, the staff add them to the app, set their pick-up times and tick off attendance each day. At the end of the month they see exactly what lunch and transport cost.
How it's built
The Angular 22 frontend (SSR, zoneless, Signals) talks only over HTTP to an ASP.NET Core Web API on .NET 10, so each of the three layers can be run and tested on its own. The API reads and writes a SQL Server database with raw ADO.NET and parameterized SQL, with no ORM. The schema is an SSDT project built and deployed with sqlpackage, and SQL Server runs in Docker on Azure SQL Edge, which also works on Apple Silicon. One script starts the database, deploys the schema and launches the API and the UI, and another builds everything and runs both test suites. API errors follow the RFC 9457 Problem Details standard, and CORS only allows the UI's own origin. The API is tested with xUnit and the UI with Vitest.
- Angular
CRBRVS Website
The official website of the rap artist CRBRVS. Fans can listen to the music right on the page, browse the merch and get in touch for bookings or collaborations. It's a single scrolling page that shows off the artist's style.
Features
- Custom audio player: play, seek, drag-to-seek and keyboard controls.
- Merch: a showcase of the artist's merchandise.
- Contact form: booking and collaboration requests go straight to the artist's email.
Use case
An event organizer hears a track, listens to the rest in the player and sends a booking request through the contact form, all without leaving the page.
How it's built
Built with Angular 22, zoneless and signal-based, rendered with SSR and prerendering, and hosted on Firebase. The audio player is custom-built on the HTML audio element, with a progress bar you can click, drag or move with the keyboard. Songs and merch are plain JSON files, so new releases are added without touching any code. Styling is plain CSS with design tokens and a trimmed copy of Bootstrap's grid, with no Bootstrap JavaScript. The contact form sends mail straight from the browser through EmailJS. It is covered by 85 unit tests with Vitest, including ones that simulate clicks and dragging in the audio player.
- Angular
TestBakery Sibiu
An online storefront for a bakery in Sibiu. Visitors browse the products by category and put together a cart. The order is sent through a contact form and confirmed by email, with no online payment involved.
Features
- Browse by category: products grouped by category, with a search.
- Saved cart: the cart is kept between visits.
- Order by email: orders and questions go straight to the bakery's inbox.
Use case
A customer planning a birthday picks a cake and two trays of pastries, sends the order with a pick-up date, and the bakery replies to confirm.
How it's built
Built with Angular 22 (SSR, zoneless, Signals), with every page prerendered to static HTML and hosted on Firebase. The product catalog loads from Firebase Realtime Database, with a session cache first and a static JSON file as a fallback, so the store still works if Firebase is slow or down. Firebase gets five seconds to answer before the fallback takes over. The catalog reaches the page through Angular's rxResource, which turns the request into signals for the loading state and the data. The cart is a signal-based service saved to localStorage, restored only after the first render so the server and the browser agree on what is shown. Orders and questions go out by email through EmailJS, with no payment step and no backend of its own.
- Angular
- .NET
Customer Management System
A web app a merchant can use to keep their customer records in one place: names, contact details, addresses and what each customer bought. Records sit behind a login and every change is tracked. It is also my playground for learning, so it keeps getting rebuilt with newer ideas.
Features
- Secure login: hashed passwords, short-lived session tokens and a rate limit on login attempts.
- Fast, searchable lists: the database searches, sorts and pages the records, and the current view exports to CSV.
- Safe lifecycle: a customer has to be deactivated before being deleted, and bulk actions handle a whole selection with one confirmation.
- Audit log: a per-customer and global history of what changed, who changed it and when.
- Products and purchases: a 50-product catalog with the purchases of each customer, and stock and buyers per product.
- Demo data and status: a test mode that generates realistic sample customers in one click, and a live banner if the API stops responding.
Use case
A shop owner looks up a returning customer, sees which products they bought and when, and updates their address.
How it's built
The Angular 22 frontend (SSR, zoneless, Signals) calls a layered ASP.NET Core Web API on .NET 10 (controllers, business logic, data access, domain). The API reaches SQL Server only through stored procedures, called with plain ADO.NET and no ORM, and the schema is an SSDT project deployed with sqlpackage. Login issues a signed JWT that expires after 15 minutes, checked in one place in the middleware, and passwords are hashed with salted PBKDF2 and compared in constant time. Search, sorting and paging run in the database, not in the browser, so the list stays fast as it grows. Over time it moved from NgModules and zone.js to Signals, from unsalted password hashes to PBKDF2 with a rate-limited login, and from browser popups to a custom confirmation dialog. The API is tested with xUnit and the UI with Vitest, focused on the login and session chain.
- Angular
- .NET
Employee Management System
The twin of the Customer Management System, built for an employer to manage their staff. It keeps each employee's contact details, office, department and salary history in one place. Records sit behind a login and every change is tracked.
Features
- Secure login: hashed passwords, short-lived session tokens and a rate limit on login attempts.
- Fast, searchable lists: the database searches, sorts and pages the records, and the current view exports to CSV.
- Safe lifecycle: an employee has to be deactivated before being deleted, and bulk actions handle a whole selection with one confirmation.
- Audit log: a per-employee and global history of what changed, who changed it and when, including salary changes.
- Organization structure: offices, departments and cost centers with headcount and total gross salary, plus a dated salary history per employee.
- Demo data and status: a test mode that generates realistic sample employees in one click, and a live banner if the API stops responding.
Use case
HR gives an employee a raise: the new salary is dated, appears in their salary history and is recorded in the audit log.
How it's built
Same stack and architecture as the Customer Management System: Angular 22 (SSR, zoneless, Signals), a layered ASP.NET Core Web API on .NET 10 with JWT authentication, and SQL Server accessed only through stored procedures. On top of that sits an organization structure of offices, departments and cost centers, each with its own headcount and total salary. Every salary change is a new dated record, so the full pay history stays in the database and in the audit log. The database is seeded with a test login and demo offices, departments and cost centers, so the app is usable right after the first start. Both apps share naming and data conventions, so what is learned in one carries straight over to the other. The business logic is covered by xUnit tests and the Angular login and list logic by Vitest.
- Angular
- .NET
Local Network Discovery
A scanner that finds every device on your home or office network and works out what each one is: a router, a printer, a TV, a smart bulb. It shows the name, maker and open services of each device, along with how healthy the network is. It also remembers past scans, so you can tell which devices are new and which have gone offline.
Features
- Device identification: MAC vendor, hostname, open ports and protocol replies combine into a best guess of what each device is.
- Live progress: every phase of the scan, host by host, streams to the page as it happens.
- Network conditions: latency, jitter, packet loss and the WiFi signal, channel and noise of the scanning machine.
- Device history: every device ever seen is remembered, with when it was first and last seen and whether it is online now.
- Printer and smart-device details: model, serial number, page count and toner level from printers, plus friendly names from TVs, bulbs and media devices.
- Live API log: a panel that streams what the scanner is doing behind the scenes, line by line.
Use case
Someone notices their WiFi is slow, runs a scan and finds an unknown device on the network, along with high packet loss on a crowded channel.
How it's built
A .NET 10 Web API pings every address in the subnet, 20 at a time, then examines each host that answers with ARP, DNS/mDNS, NetBIOS and TCP/UDP port scans. SNMP, UPnP and HTTP-banner probes are hand-rolled with no outside libraries, and they only run when the matching port is open, so hosts that don't use them cost nothing extra. The device type is guessed from the MAC vendor, the ping TTL, the open ports and the hostname. Every device is saved to SQLite by MAC address, and details learned in earlier scans are never overwritten by a probe that came back empty. The Angular 22 frontend (zoneless, Signals) follows the scan live through Server-Sent Events. Both halves are covered by unit tests, with xUnit for the API and Vitest for the UI.
- Python
Tool-Chip Contact Length
When a machine tool cuts metal, the chip it peels off touches the tool for a short distance before curling away, and that distance matters for tool wear and cutting quality. This program measures it automatically from high-speed camera photos. What used to be measured by hand, frame by frame, now takes one command.
Features
- Batch processing: measures every camera frame in a folder in one run.
- Automatic image cleanup: each photo is cropped, turned black and white and smoothed, so the tool and the chip stand out.
- Line detection: finds the tool's edge and the chip's edge and measures the gap between them in pixels.
- Annotated results: saves each measured frame with the lines and the contact length drawn on it, and skips frames where both edges can't be found instead of guessing.
- Step-by-step diagnostics: a six-panel plot per frame shows every processing stage, so each result can be checked visually.
- One-command setup and logs: one script finds Python, installs anything missing, runs the program and logs a summary of images processed, results produced and time taken.
Use case
A research team films a cutting test at thousands of frames per second, drops the images into a folder and runs one command, getting a measured, annotated image for every frame.
How it's built
A Python batch pipeline built on OpenCV and NumPy that runs every frame in a folder through the same steps. Each photo is resized to a fixed width so all the pixel thresholds behave the same, then cropped to the right half, where the cut always happens. Otsu thresholding turns it black and white, and morphological closing and dilation fill the gaps so the tool and the chip form one solid shape. Canny edge detection traces its outline, and a Hough transform finds the two straight lines whose gap is the contact length. Each frame is saved with the measurement drawn on it, next to a six-panel plot of every step for checking the result. A frame that fails is logged and skipped without stopping the batch, and the code is covered by pytest and checked with Ruff and mypy.
- HTML
- CSS
- JS
CV Builder
A simple tool for writing a CV right in the browser. You fill in your details and watch the CV take shape next to the form as you type. When it looks right, you download it as a PDF, ready to send.
Features
- Live preview: the CV updates as you type, with sections for work experience, education, skills, languages and a photo.
- PDF export: download the finished CV as a paginated PDF in one click.
- Saved and portable: your data saves automatically in the browser and can be exported to or imported from a JSON file, so you can reuse and share it.
Use case
A job seeker fills in their CV once, downloads it as a PDF for an application, and keeps the JSON file to tweak it for the next one.
How it's built
Written in plain HTML, CSS and vanilla JavaScript, with no framework, build step or backend: it runs by opening a single page. The preview redraws as you type and is split into A4 pages with a page number in the footer. The page breaks are worked out from the layout itself, so a job, a school or a heading is never cut in half between two pages. The PDF is generated in the browser with html2pdf.js, with a fix that stops a nearly empty extra page from appearing when the content just fills the last one. Your data is saved to localStorage automatically and can be exported or imported as a JSON file. Nothing is uploaded anywhere, so all data stays on your own device.
YouTube & GitHub
There's more
These are only some of the things I build. On my YouTube channel I show projects in action and walk through how they work, and on GitHub you'll find the source code of everything here and more.
Subscribe on YouTube to catch the next video, and follow me on GitHub to see what I'm working on right now.