Przejdź do treści
Maciej Rzepka

Cześć!

Frontend & full-stack developer. Robię szybkie, dopracowane aplikacje webowe, od pierwszego szkicu po wdrożenie.

  • TypeScript
  • React
  • NextJS
  • NuxtJS
O mnie

Buduję aplikacje,które ludzie lubią

Jestem programistą z wieloletnim doświadczeniem w tworzeniu aplikacji webowych.

Lokalizacja
Bydgoszcz, Polska
Specjalizacja
Full-stack Developer
Języki
Polski, angielski

Na co dzień zajmuję się tworzeniem aplikacji w oparciu o NextJS, w domowym zaciszu eksperymentuję z mniej znanymi frameworkami i technologiami, takimi jak Svelte, Astro czy Nuxt.

Moje pomysły na projekty powstają w oparciu o doświadczenie zdobyte przy realizacji projektów komercyjnych, a także w ramach własnych eksperymentów i zdobywanych umiejętności. Niestety na potrzeby tego portfolio nie mogłem pokazać projektów komercyjnych wykonywanych dla zewnętrznych firm, ale w sekcji „Projekty” znajdziesz moje autorskie pomysły i realizacje :)

TypeScriptReactNext.jsNuxt.jsAstroSvelteTailwind CSSPythonPostgreSQLConvexSupabaseVitePrismaDrizzle ORMREST APIDockerGitGitHub ActionsVercel
01W przygotowaniu

Courtto Academy

Multi-tenant SaaS dla szkół sportów rakietowych

Dane widoczne na zrzutach zostały wygenerowane przez AI na potrzeby demonstracji.

Celem projektu było stworzenie złożonego systemu SaaS do zarządzania szkołami sportów rakietowych - pomysł wziął się stąd, że moja własna szkoła tenisowa nie miała żadnego takiego narzędzia. Aplikacja jest w dużej mierze kompletna i obejmuje: tworzenie placówek, dodawanie członków, zarządzanie kortami oraz ich dostępnością, tworzenie grup zajęciowych oraz obsługę płatności.

Największym wyzwaniem okazała się architektura multi-tenant. Odizolowanie danych poszczególnych szkół wymagało szczególnej ostrożności - nie tylko w warstwie serwerowej, ale także po stronie bazy danych. Każde zapytanie zamknąłem w warstwie serwisów, gdzie filtrowanie po identyfikatorze organizacji i sprawdzanie uprawnień dzieje się w jednym miejscu, a szczelność tej izolacji pokrywają testy.

  • +Tego samego kortu ani trenera nie da się zarezerwować dwa razy na ten sam termin, bo pilnuje tego ograniczenie EXCLUDE USING gist w PostgreSQL, a nie tylko walidacja w aplikacji.
  • +Zajęcia cykliczne zapisuję jako godzinę lokalną i strefę czasową, dzięki czemu „w poniedziałki o 17:00” zostaje o 17:00 także po zmianie czasu.
  • +Zapisy na zajęcia blokują wiersz w bazie, więc dwie osoby klikające naraz nie zajmą tego samego ostatniego miejsca. Kto się nie zmieści, trafia na listę rezerwową.
  • +Płatności działają dwutorowo. Szkoły płacą abonament za Courtto, a rodzice płacą szkołom przez Stripe Connect, gdzie sprzedawcą jest już sama szkoła.
Rola
Solo - architektura, baza danych, backend i frontend
Stack
Nuxt.jsPostgreSQLDrizzle ORMBetter AuthStripe

Zrzuty ekranu

Grafik zajęć
Zarządzanie kortami
Logowanie
022026

Raveomat

Platforma wydarzeń i sprzedaży biletów

Dane widoczne na zrzutach zostały wygenerowane przez AI na potrzeby demonstracji.

Raveomat to platforma biletowa dla imprez muzycznych: publiczny katalog wydarzeń oraz panel, w którym organizatorzy sami je wystawiają. Zrobiłem go z myślą o własnych imprezach, które jako artysta z wieloletnim stażem zdarzało mi się współorganizować.

Najwięcej nauczyłem się przy logowaniu. Na początku serwer i przeglądarka trzymały sesję osobno i po odświeżeniu tokenu potrafiły się rozjechać. Ostatecznie obie strony korzystają z tego samego klienta Supabase i tych samych ciasteczek, a wejście do panelu sprawdzam dwa razy, w middleware i w politykach RLS po stronie bazy.

  • +Publiczne formularze przechodzą przez Astro Actions, więc walidacja Zod, honeypot i limit zapytań siedzą obok siebie w jednym miejscu.
  • +Limit zapytań jest liczony osobno dla adresu IP i dla maila, a oba identyfikatory są hashowane - w licznikach nie lądują surowe dane.
  • +Kiedy Redis przestaje odpowiadać, limiter wraca do liczników w pamięci, zamiast wyłączać cały formularz.
  • +Plakaty są przycinane na canvasie jeszcze w przeglądarce i dopiero taki gotowy kadr leci do Storage.
Rola
Solo - frontend, warstwa SSR i baza danych
Stack
AstroSvelte 5SupabaseTailwindZod

Zrzuty ekranu

Lista wydarzeń
Szczegóły wydarzenia
Strefa partnerów
Logowanie
032026

Saboteur

Wieloosobowa gra karciana w przeglądarce

Grafiki w grze są tymczasowe i czekają na docelową oprawę.

Saboteur to przeglądarkowa wersja gry karcianej o tym samym tytule. Gra od trzech do dziesięciu osób, dołączanie do pokoju odbywa się przez sześcioznakowy kod, bez zakładania kont. Stworzyłem ją głównie po to, żeby pograć wspólnie ze znajomymi :)

Najwięcej myślenia wymagało ukrywanie informacji. Cała zabawa polega tu na tym, że nie wiesz, kto jest sabotażystą, więc nie wystarczy schować roli w interfejsie - klient nie może jej w ogóle dostać. Publiczny stan gry, karty na ręce i własna rola to trzy osobne zapytania - role odsłaniają się dopiero na koniec rundy. W zakładce sieciowej wszystko jest ukryte.

  • +Nowa karta musi pasować krawędziami i łączyć się z siecią korytarzy, co sprawdza przeszukiwanie wszerz od karty startowej.
  • +Puste pokoje są kasowane przez cron, który co pół minuty usuwa graczy milczących od czterdziestu pięciu sekund.
  • +Host ustawia liczbę graczy, liczbę rund, czas na turę i dodatkową zasadę za złamane narzędzie, a reszta pokoju widzi te zmiany na żywo.
Rola
Solo - logika gry, backend czasu rzeczywistego i frontend
Stack
React 19ConvexViteTailwindMotion

Zrzuty ekranu

Poczekalnia
Podsumowanie rundy
Ekran startowy
04Interaktywne

PaperUI

Własna biblioteka komponentów na bazie bits-ui

PaperUI to zestaw komponentów Svelte, który powstał przy okazji innej pracy. Budowałem panel do jednej ze swoich aplikacji i chciałem, żeby wszystko trzymało się stylistyki, którą sobie założyłem, więc kolejne kawałki interfejsu robiłem sam. Uzbierało się ich dwadzieścia jeden, więc zebrałem je w jedno miejsce i doprowadziłem do wspólnego porządku. Trzynaście widzisz poniżej - to dokładnie te same komponenty co w bibliotece, tyle że w kolorach tej sekcji.

Komponenty działają na żywo. Klikaj, przełączaj, sprawdzaj klawiaturą.

Zobacz kod
Statusy
gotowe
w toku
nowe
szkic
archiwum
Stan

bez nazwy · Domyślny · komfort · jednorazowy

Kontakt

Porozmawiajmy