Consulting & Freelance

I was in charge of the front-end, turning designs into working pages.

I connected the front-end to the back-end and set up user access.

See the projects below for more details on my work.

Course Recommendation Chat

Context-Aware AI Assistant

Frontend: React, Javasript

Design: Figma

Did front-end architecture and implementation of this embeddable chat widget.

The Course Recommendation Chat is an AI-powered, iframe-based customer assistant that leverages GPT-4 to offer personalized course suggestions, answer user questions, and guide visitors through available learning options on any host page.

Built a responsive UI that seamlessly integrates into host pages via the postMessage API.

Designed the conversation interface and prompts for GPT-4 suggestions, ensuring smooth user flows and real-time feedback.

Iterated on the UX and styling (using Figma mocks) to boost engagement—handling all state management with React Context.

StockStories AI

Financial Discussion Aggregator

Frontend: Next.js (SSR/SSG), TypeScript, Sass

Design: Figma

Led the front-end build with Next.js, creating a fast, SEO-friendly interface for viewing aggregated forum discussions.

StockStories AI is a financial discussion aggregator that consolidates thousands of forum posts and comments from multiple sites, allowing users to discuss stocks and benefit from daily AI-generated analyses of market movements and sentiment.

Crafted a custom Sass framework to display data-dense tables and sentiment highlights clearly across breakpoints.

Implemented live-update components to render new posts in real time, integrating with provided data endpoints.

Collaborated closely with designers to refine responsive layouts and interactive elements for filtering and pagination.

Real Estate MVP

Full-Stack Platform for Enterprise Client

Frontend: Next.js, Material-UI, Typescript, React, Sass

Backend: Firebase Firestore, Firebase Auth

Map Integration: Google Maps API, Mapbox API

A comprehensive real estate MVP developed for an enterprise client. The platform supports multiple user roles (buyers, agents, agencies) with distinct dashboards and role-based access.

Buyers can search and save listings, agents manage listings and analytics, while agencies oversee overall performance metrics.

Features include a hybrid Google Maps/Mapbox system, Firebase-backed auth, and optimized page loads via static generation (SSG) with Next.js.

I was responsible for the full-stack architecture and UI consistency across dashboards while keeping the code DRY and maintainable.

Chat Widget AI (Private)

AI-Powered Support Chat for Web Integration

Frontend: React, JavaScript, SCSS

Backend: Node.js, Firebase Functions

Testing: Tampermonkey

Developed an embeddable AI chat widget with full support for real-time interaction and postMessage communication between host and iframe.

Includes state management via React Context and a minimal SCSS-based responsive layout.

The chat leverages a Firebase/Node backend for message relay and integrates with OpenAI for GPT-driven suggestions.

Tampermonkey scripts were used to test widget injection on live client sites during development.

Hobby

These are self-initiated, fun coding projects I built to explore new ideas and technologies.

See the list below for more details on each project.

Terminal Time Tracker

Bash-Inspired Workflow Analytics

Core: C (POSIX), fgets()/sscanf(), strptime()/mktime()

Storage: CSV files

DevOps: Cron (optional)

The Terminal Time Tracker is a command-line tool written in C that lets users log and review project start/end times and agendas directly in the terminal, storing entries as CSV rows for easy automation or spreadsheet import.

Built a minimalist, terminal-based time tracker in C to log project start/end times and agendas directly into a CSV.

Session data is appended as Project,Agenda,Start,End rows—perfect for later analysis or import into spreadsheets.

Provided a companion reader that parses each row, computes durations via strptime()/mktime(), and prints summaries, for example:

Project: BPS
Agenda: Aktie grej
Start: 2025-04-11 15:56:01
End:   2025-04-11 21:15:25
Time Worked: 05h 19m 24s

Key technical highlights:
Robust input handling: fgets() + sscanf() to safely read CSV fields.
Reliable time math: POSIX struct tm conversions and difftime().
Modular design: Separate logging and reading binaries for clear separation of concerns.

Vim-Mail CLI Client

Terminal Email Sender with Vim & C

Core: C11, libcurl 8.x, OpenSSL 3.0

Scripting: Bash

Build: Makefile

Editor: Vim

Vim-Mail CLI Client is a custom terminal-based email utility combining Vim, C, and Bash scripts to let users compose and send emails directly from the shell: you enter the recipient address, Vim opens for you to write the message, then on :w :q it’s sent via SMTP.

This project is a work in progress: a terminal-based email client that lets you compose messages in Vim and send them straight from your shell.

Core SMTP Implementation:

1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <curl/curl.h>
5
6// Core SMTP send logic
7CURL *curl = curl_easy_init();
8if (curl) {
9    curl_easy_setopt(curl, CURLOPT_URL, smtp_url);
10    curl_easy_setopt(curl, CURLOPT_USERNAME, smtp_user);
11    curl_easy_setopt(curl, CURLOPT_PASSWORD, smtp_pass);
12    curl_easy_setopt(curl, CURLOPT_MAIL_FROM, smtp_user);
13    // … set recipients, payload, etc.
14    CURLcode res = curl_easy_perform(curl);
15    // handle res
16}

Helper Scripts:

load_env.sh: loads SMTP/IMAP credentials from .env.

new_email.sh: scaffolds an email template, opens it in Vim, and then invokes send_mail.

read_mail.sh: fetches IMAP inbox headers via curl and opens them in Vim.

Build System:

Makefile: compiles with -Wall -Wextra -O2 and provides make targets for build and clean.

Keystroke Dynamics Analyzer

Low-Latency Input Capture

Core: C17, Linux 6.x Input Subsystem

Timing: gettimeofday(), struct timeval

Built as a stress-relief project to dive into Linux input handling and test a second-hand mechanical keyboard at the kernel level.

The Keystroke Dynamics Analyzer is a terminal-based utility that reads raw /dev/input/event* events on Linux, measuring precise inter-keystroke delays and key-down latencies to analyze typing patterns and response times :contentReference[oaicite:1]{index=1}.

Low-Level Event Capture:

1// Read key press and compute response time
2struct input_event ev;
3ssize_t n = read(fd, &ev, sizeof(ev));
4if (ev.type == EV_KEY && ev.value == 1) {
5    struct timeval current_time;
6    gettimeofday(&current_time, NULL);
7    long sec  = current_time.tv_sec  - ev.time.tv_sec;
8    long usec = current_time.tv_usec - ev.time.tv_usec;
9    double response_ms = sec * 1000.0 + usec / 1000.0;
10    printf("Key pressed: %s (%d) | Response time: %.3f ms\n",
11           keycodes[ev.code], ev.code, response_ms);
12}

Highlights:

Uses open(), read(), and close() on /dev/input/eventX for direct device I/O.

Maps EV_KEY codes to human-readable names via a lookup table (keycodes[]).

Achieves millisecond-precision timing with gettimeofday() and arithmetic on struct timeval.

Learnings:

Gained hands-on experience with file descriptors and binary data structures in C.

Explored how the Linux kernel exposes input devices through special files.

Yahoo AI Stock Tracker

AI-Powered Real-Time Stock Dashboard

Core: TypeScript, Node.js

UI: blessed

Data & API: yahoo-finance2

AI: OpenAI API

The Yahoo AI Stock Tracker is a terminal-based dashboard that aggregates real-time stock quotes from Yahoo Finance and leverages AI to generate concise, up-to-date insights for each symbol.

Terminal-based stock dashboard, building a responsive, interactive UI with blessed and TypeScript.

UI Initialization & Layout:

1import blessed from 'blessed';
2
3const screen = blessed.screen({
4  smartCSR: true,
5  title: 'Yahoo AI Stock Tracker'
6});
7
8const table = blessed.listtable({
9  parent: screen,
10  top: 0, left: 0, width: '50%', height: '50%',
11  border: 'line',
12  align: 'left',
13});

Highlights:

Four resizable panels (Full Table, Movers, Recent Changes, AI Insights) for clear data segmentation.

Real-time quotes fetched via yahoo-finance2 with live-update components.

AI-generated summaries in the Insights panel, refreshed every minute using the OpenAI API.

Custom keybindings for filtering symbols, pausing updates, and navigating panels seamlessly.

Yahoo AI Stock Tracker

Keyword Job Crawler

Web Scraper & Crawler

Core: Java 17

Libraries: Jsoup

Build: Gradle

The Keyword Job Crawler is a command-line tool that navigates and scrapes multiple job boards to collect postings matching a set of user-defined keywords.

A CLI tool that I built to recursively crawl job boards (Academic Work, Arbetsförmedlingen, Indeed) and extract links matching a customizable keyword list.

Highlights:

Visited Set: Prevents duplicate visits via a HashSet<String>.

Domain Filtering: Keeps the crawl scoped to target sites only.

Keyword Matching: Parses <h1> elements for exact keyword hits.

Usage:

Clone the repo and navigate to the project root.

Build and run with Gradle:

1./gradlew build
2./gradlew run --args="https://start-url.com"

MDX Code Example Showcase

Utilities for MDX Files

Core: JavaScript, React, Next.js

Styling: SCSS

Parsing: gray-matter

Formatting: MDX

I built a suite of utilities in React/Next.js to turn raw MDX files into beautifully styled code-example pages, solving the pain point of poorly formatted snippets in technical books.

Front-Matter Parsing & Glossary Integration:

1import matter from 'gray-matter';
2import { Glossary } from '../components/Glossary';
3
4export function parseMDX(source) {
5  const { content, data } = matter(source);
6  return {
7    content,
8    glossary: data.glossary // front-matter terms
9  };
10}

Highlights:

Extracts metadata and glossary entries via gray-matter front-matter parsing.

Renders <CodeBlock> and <Glossary> components for consistent styling and inline term definitions.

SCSS-driven theme with syntax-aware highlighting, line numbers, and copy-to-clipboard buttons.

Workflow:

Authors drop an MDX file into pages/, run the Next.js build, and instantly get a live preview with styled examples and sidebar glossaries.

Next Steps:

Deal with the errors..

MDX Code Example Showcase

GUI Wiki Scraper

Interactive Crawler + Scraper

Stack: Java 21, Swing, Jsoup

A hobby project that merges web-crawling with web-scraping for wikis and game sites:

Recursively follows links and collects page meta-data (titles, headings).

Extracts full paragraphs and HTML tables, then saves tables as JSON.

Lets you pick an output folder and writes neatly formatted files.

Simple Swing GUI so you can point-and-scrape without touching the CLI.

MP3 Player

React Audio Visualizer & Sprite Animation

Frontend: React, SCSS Modules, Canvas API, Web Audio API, React Icons

Built a standalone React MP3 player with a real-time audio visualizer (waveform + starfield + sprite-based dancer).

Implemented track navigation, play/pause, seek bar, and volume controls using Web Audio API and HTML5 <audio>.

Preloaded sprite frames (040–071) for a dancing animation that pulses on beat, and drew a thin, glowing waveform over a flickering starfield via Canvas API.

Responsive design: sidebar track list on desktop, moves below the player on mobile (≤ 768px).

Styled entirely with SCSS modules, and used react-icons for intuitive control buttons.

School

Office Life Simulator

2D Java Game Engine

Core: Java 11

Rendering: Java Swing

Data: CSV Parsing

Built a 2D game engine from scratch in pure Java to simulate office life—handling sprite sheets, collision detection, and dialogue trees without any external game libraries.

The Office Life Simulator is a 2D game built in Java that recreates day-to-day office experiences—characters navigate tile-based floorplans, interact with NPC colleagues, and progress through branching dialogue scenarios, serving both educational and entertainment purposes.

Highlights:

Map Loader: Parsed CSV level files into tile maps and interactive NPC placements.

Entity System: Managed multiple moving objects with buffered rendering for 60 FPS smoothness.

Dialogue Engine: Script-driven conversation trees with branching choices and persistent state.

Learnings:

Deepened understanding of real-time loops and Swing’s repaint() mechanism.

Optimized memory usage by pooling sprite objects and reusing BufferedImages.

Gaming Community Portal

Spring Boot Forum System

Backend: Spring Boot, Spring MVC, Spring Security

Database: MySQL, JPA/Hibernate

Templating: Thymeleaf

Developed a full-stack forum portal using Spring Boot and Thymeleaf to power user-generated discussions with admin moderation and real-time notifications.

The Gaming Community Portal is a Spring Boot–based forum system where gamers can register, post threads, and interact via real-time notifications; it features role-based moderation for administrators, OAuth2 social login, and optimized SQL queries to maintain performance under high concurrency.

Sample Controller & Security Config:

1@Controller
2public class PostController {
3  @GetMapping("/posts/{id}")
4  public String viewPost(@PathVariable Long id, Model model) {
5    Post post = postService.findById(id);
6    model.addAttribute("post", post);
7    return "post/view";
8  }
9}
10
11@Configuration
12public class SecurityConfig extends WebSecurityConfigurerAdapter {
13  @Override
14  protected void configure(HttpSecurity http) throws Exception {
15    http.authorizeRequests()
16        .antMatchers("/admin/**").hasRole("ADMIN")
17        .antMatchers("/posts/**").authenticated()
18        .and().formLogin()
19        .and().csrf();
20  }
21}

Highlights:

OAuth2 Integration: Allowed users to sign in via Google and Facebook.

Reactive Notifications: Used Server-Sent Events (SSE) for live updates on new replies.

SQL Optimization: Tuned complex JOIN queries for fast thread loading under high concurrency.

Learnings:

Spring Security DSL for fine-grained URL and role-based access controls.

Implemented pagination and sorting via Spring Data JPA to handle large post volumes efficiently.

WebbservicesJ22SK

Java RESTful Web Services Suite

Core: Java 17

Framework: JAX-RS (Jersey)

Build: Maven (Wrapper)

JSON: Jackson

A Maven-based Java web service project that exposes RESTful endpoints for predictions, SMHI weather data, and user registration—built as part of the J22 SK course curriculum.

WebbservicesJ22SK is a course-based Java RESTful service suite using JAX-RS (Jersey) that serves static prediction and SMHI weather data via HTTP GET endpoints and provides a JSON-based user registration API, built with Java 17, Jackson for JSON processing, and packaged via Maven Wrapper.

Highlights:

Loads static JSON files (predictions.json, smhipredictions.json, userreg.json) and serves them via HTTP GET.

Implements a user registration POST endpoint with @POST and @Consumes(MediaType.APPLICATION_JSON), persisting to userreg.json.

Uses Jackson for seamless JSON marshalling/unmarshalling and includes error handling for invalid payloads.

Usage:

Build and run with the Maven wrapper:

./mvnw clean package

java -jar target/webbservicesj22sk.jar