Alpha EdTech · Team project
Food Point: planning food-centered events
A platform to plan food-centered events: the event, the place on a map, the menu with its ingredients, the guests and the shopping list. A single-page app in plain JavaScript, no framework, built by a team.
Food Point
Address: /Replay
It loads the original images, about 3 MB. The test account is in the server panel.
A replay: the frontend is the 2024 one, unchanged, and in Portuguese, as it was. The Express and PostgreSQL backend became a simulation in your browser, with the same routes, validation and answers, and password recovery shows here the code it would e-mail. The postal code, the map and the address use the real public APIs.
In 30 seconds
- A team project of 4 people at Alpha EdTech, in about 4 weeks, with no frontend framework.
- I wrote most of the frontend: the SPA router, the home page and the create-event flow, with a map and a menu.
- Presented at a demo day. The 2024 frontend runs above, unchanged, on a simulated server.
- When
- Apr — May 2024 · ~4 weeks
- Role
- Developer · team of 4, no lead
- Origin
- Team project at Alpha EdTech
- Stack
- JavaScript, HTML, CSS, Node.js, Express, PostgreSQL, Leaflet, JWT, Nginx
Context
In April 2024, about six months after I joined Alpha EdTech, the cycle's challenge was an events app, with lists and records to create and edit. My team chose food-centered events: you put together the event, the menu and the guest list, and the platform gathers every dish's ingredients into one shopping list.
There were two rules: no framework on the frontend and only Express on the backend. It was early in the program, and what was graded was technical knowledge, not the product.
We were four, with no lead: decisions were made by consensus. I was a developer.
The problem
Without React or Vue, everything a framework hands you had to be written by hand: changing pages without a reload, building each screen through the DOM, carrying data from one screen to the next and talking to the API.
And creating an event is a flow of several steps (details, place, menu and guests), each with its own screen, which had to talk to a backend being written at the same time, by other people.
My part
I built most of the frontend and some parts of the backend. Other screens, such as login, the profile, password recovery and the shopping list, are my teammates' work.
- The single-page app's router, in plain JavaScript, with routes that require login.
- The frontend's API layer and components shared across screens.
- The home page and the whole create-event flow: details, place (postal code, a Leaflet map and a readable address from Nominatim) and menu. The guests screen too.
- On the backend: the Express setup, the routes that serve the pages, the PostgreSQL connection and login.
- The server's Nginx: a reverse proxy with HTTPS in front of Node.
- About 60% of the design in Figma. The prototype is lost: the account that created it no longer exists.
- In the final stretch, most of the integration fixes between frontend and backend.
Technical decisions
A hand-written router
Routes are an object: for each path, the function that builds the screen, the title, the description and whether it needs login. To change pages, any screen fires a custom event (onstatechange); the router calls pushState and redraws the root. The back button goes through popstate. Before building a protected screen, the router asks the API who is logged in and, if nobody is, sends you to login.
Screens as functions
Each screen is a function that returns a DOM element, built with createElement, with no templates and no virtual DOM. What one screen needs to pass to the next, like the event just created, travels with the navigation event, and the router hands it to the next screen's function.
The place, from postal code to address
The place can come from the browser's location, a postal code or a click on the Leaflet map, and it is saved as coordinates. Showing just “-23.17,-45.88” meant nothing to anyone, so the coordinates go through OpenStreetMap's Nominatim, which returns a readable address. All of it is called straight from the browser, without going through our server.
Nginx in front of Node
On Alpha EdTech's server, Nginx took requests over HTTPS and passed them to Node, and anything arriving over HTTP was redirected to HTTPS. The login cookie is marked secure, so the browser only sends it over HTTPS.
Integration in the final stretch
With screens and API built in parallel, the last week was about putting them together. I fixed events firing twice in the menu components and added debounce, loading screens while the API answers, logout and the 404 page, plus a security fix in image uploads.
Architecture
Outcome
We presented Food Point at a demo day, to a panel of students from other teams and partner companies of Alpha EdTech. It ran on Alpha's server, where a few people created accounts and events. That server is gone, the data was lost, and there was no usage feedback beyond the presentation.
In January 2025, I put the project in Docker to run it locally and record a demo (at the time of the challenge, we hadn't learned Docker yet).
The demo at the top of this page runs the 2024 frontend unchanged. Only the server is simulated, in your browser, with the same routes and answers.