Celebrating Your Wins: What Made Your Week Unforgettable
As developers, we often focus on what’s broken, what’s next, or what we haven’t shipped yet. But growth happens when we pause and reflect on what did work — the small bugs we fixed, the feature we shipped, or the new concept we finally understood.
In this tutorial, we’ll build a simple "Weekly Wins Tracker" using Node.js and Express, with data stored in a JSON file. It's beginner-friendly, code-heavy, and perfect for celebrating your progress — one week at a time.
By the end, you’ll have a working web app where you can:
- Add your weekly win
- View all wins
- Celebrate your progress with emoji confetti 🎉
Let’s get started!
Step 1: Set Up Your Project
Create a new directory and initialize a Node.js project:
mkdir weekly-wins-tracker
cd weekly-wins-tracker
npm init -y
Install Express:
npm install express
Install nodemon for auto-restarting during development (optional but recommended):
npm install --save-dev nodemon
Update your package.json scripts:
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js"
}
Step 2: Create the Server
Create server.js:
const express = require('express');
const fs = require('fs');
const path = require('path');
const app = express();
const PORT = 3000;
// Middleware to parse JSON and serve static files
app.use(express.json());
app.use(express.static('public'));
We’re using:
-
express.json()to parse incoming JSON -
express.static('public')to serve HTML, CSS, and JS files
Step 3: Set Up Data Storage
We’ll store wins in a JSON file called wins.json.
Create wins.json in your project root:
[]
Now, add helper functions to read and write wins:
const WINS_FILE = path.join(__dirname, 'wins.json');
// Read wins from file
function readWins() {
const data = fs.readFileSync(WINS_FILE);
return JSON.parse(data);
}
// Write wins to file
function writeWins(wins) {
fs.writeFileSync(WINS_FILE, JSON.stringify(wins, null, 2));
}
Step 4: Build the API Endpoints
Let’s create three routes:
-
GET /wins– get all wins -
POST /wins– add a new win -
GET /– serve the frontend
Add the routes:
// Get all wins
app.get('/wins', (req, res) => {
try {
const wins = readWins();
res.json(wins);
} catch (err) {
res.status(500).json({ error: 'Failed to read wins' });
}
});
// Add a new win
app.post('/wins', (req, res) => {
const { text } = req.body;
if (!text || text.trim() === '') {
return res.status(400).json({ error: 'Win text is required' });
}
const newWin = {
id: Date.now().toString(),
text: text.trim(),
date: new Date().toISOString().split('T')[0]
};
const wins = readWins();
wins.push(newWin);
writeWins(wins);
res.status(201).json(newWin);
});
Step 5: Create the Frontend
Create a public folder and add index.html:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Weekly Wins Tracker</title>
<style>
body {
font-family: 'Segoe UI', sans-serif;
max-width: 600px;
margin: 40px auto;
padding: 20px;
background: #f9f9ff;
color: #333;
}
h1 { color: #4a4a98; text-align: center; }
input, button {
padding: 10px;
margin: 10px 0;
width: 100%;
box-sizing: border-box;
}
button {
background: #4a4a98;
color: white;
border: none;
cursor: pointer;
}
ul {
list-style: none;
padding: 0;
}
li {
background: white;
margin: 8px 0;
padding: 12px;
border-radius: 6px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
.confetti {
font-size: 1.5em;
margin-right: 8px;
}
</style>
</head>
<body>
<h1>🎉 Celebrate Your Wins</h1>
<input type="text" id="winInput" placeholder="I shipped my first Express app!" />
<button onclick="addWin()">Add Win</button>
<ul id="winsList"></ul>
<script>
// Load wins on page load
window.onload = loadWins
---
☕ **Playful**
Top comments (0)