Aplikasi To-do List dengan Fitur Login (Fullstack Web App)

Ilustrasi Gambar: Aplikasi To-do List.

Bagian 1: Pengantar & Perencanaan Proyek Fullstack

Halo teman-teman, selamat datang di seri artikel terbaru di ruanginformatika.com! πŸŽ‰

Dalam seri ini, kita akan belajar bareng bagaimana cara membangun aplikasi web fullstack dari nol. Kita akan mulai dari perencanaan, bikin tampilan, ngebangun backend, sampai aplikasi kita bisa online dan diakses semua orang.

Tenang aja, semuanya akan dijelaskan langkah demi langkah dengan gaya santai dan mudah dimengerti, cocok banget buat kamu yang baru mulai belajar fullstack development.

πŸ‘¨β€πŸ’» Apa yang Akan Kita Bangun?

Kita akan bikin aplikasi To-do List dengan fitur login. Jadi user bisa daftar, login, dan membuat daftar tugas harian mereka. Fitur-fitur dasarnya:

  • Registrasi dan login dengan email dan password
  • Membuat, mengedit, dan menghapus to-do item
  • Menyimpan data secara online menggunakan database
  • Menampilkan tugas secara real-time di halaman dashboard

πŸ› οΈ Tools & Teknologi yang Akan Kita Gunakan

Berikut adalah alat-alat utama dalam proyek ini:

  • Frontend: React + Tailwind CSS
  • Backend: Node.js + Express
  • Database: MongoDB (pakai MongoDB Atlas biar gampang)
  • Auth: JSON Web Token (JWT)
  • Deployment: Vercel (frontend) dan Render (backend)

πŸ“‚ Struktur Proyek

Proyek ini akan kita bagi jadi dua folder besar:

/todo-app/
β”‚
β”œβ”€β”€ client/      β†’ Frontend (React + Tailwind)
└── server/      β†’ Backend (Node.js + Express + MongoDB)

Nanti kita akan setup masing-masing bagian dan sambungkan satu sama lain. Di akhir seri, kamu akan punya aplikasi web yang lengkap dan bisa dipamerin di CV atau portofolio! 😎

πŸ“… Apa Selanjutnya?

Di artikel selanjutnya, kita akan langsung mulai dengan setup frontend menggunakan React dan Tailwind. Kita bakal bikin tampilan awal seperti halaman home, login, dan dashboard.

Untuk lanjutannya di Bagian 2: Membuat UI Frontend dengan React + Tailwind bisa next page ya! Jangan lupa share artikel ini kalau kamu suka dan mau ngajak teman belajar bareng. πŸš€

Bagian 2: Membuat UI Frontend dengan React + Tailwind

Halo kembali di seri membangun aplikasi web fullstack bareng ruanginformatika.com! πŸ‘‹

Sesuai janji di artikel sebelumnya, kali ini kita akan mulai membangun tampilan depan alias frontend dari aplikasi To-do List kita menggunakan React dan Tailwind CSS.

🧰 Langkah 1: Setup Proyek React

Kita akan menggunakan Vite karena proses setup-nya cepat dan ringan. Jalankan perintah berikut di terminal kamu:

npm create vite@latest client --template react

Lalu masuk ke folder dan install dependensi:


cd client
npm install
  

Setelah itu, kamu bisa coba jalankan proyeknya:

npm run dev

Jika berhasil, kamu akan melihat tampilan awal React di browser.

🎨 Langkah 2: Integrasi Tailwind CSS

Tailwind CSS akan kita gunakan untuk mempercepat proses styling tanpa harus mikirin file CSS manual.

Install Tailwind dengan perintah:


npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
  

Edit file tailwind.config.js jadi seperti ini:


/** @type {import('tailwindcss').Config} */
export default {
  content: [
    "./index.html",
    "./src/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
  

Lalu di file src/index.css, ganti isinya dengan:


@tailwind base;
@tailwind components;
@tailwind utilities;
  

Sekarang kamu bisa pakai class Tailwind langsung di JSX!

🧱 Langkah 3: Membuat Halaman Awal

Buat beberapa file komponen seperti ini:


src/
β”œβ”€β”€ components/
β”‚   β”œβ”€β”€ Header.jsx
β”‚   β”œβ”€β”€ TodoItem.jsx
β”œβ”€β”€ pages/
β”‚   β”œβ”€β”€ Home.jsx
β”‚   β”œβ”€β”€ Login.jsx
β”‚   β”œβ”€β”€ Register.jsx
β”‚   β”œβ”€β”€ Dashboard.jsx
  

Contoh kode sederhana Header.jsx:


export default function Header() {
  return (
    <header className="bg-blue-600 text-white p-4">
      <h1 className="text-xl font-bold">To-do App</h1>
    </header>
  );
}
  

Lalu tampilkan komponen Header di App.jsx.

🌐 Langkah 4: Navigasi Halaman

Install React Router untuk navigasi antar halaman:

npm install react-router-dom

Atur routing di App.jsx:


import { BrowserRouter, Routes, Route } from "react-router-dom";
import Home from "./pages/Home";
import Login from "./pages/Login";
import Register from "./pages/Register";
import Dashboard from "./pages/Dashboard";

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/login" element={<Login />} />
        <Route path="/register" element={<Register />} />
        <Route path="/dashboard" element={<Dashboard />} />
      </Routes>
    </BrowserRouter>
  );
}

export default App;
  

Sekarang kamu bisa navigasi antar halaman seperti aplikasi beneran!

βœ… Kesimpulan

Sampai di sini, kita sudah berhasil:

  • Setup proyek frontend dengan React + Vite
  • Integrasi Tailwind CSS
  • Membuat halaman dan komponen dasar
  • Menambahkan navigasi dengan React Router

Di artikel berikutnya, kita akan mulai membangun bagian backend API menggunakan Express dan MongoDB.

Jangan lupa simpan dan commit proyek kamu ke GitHub ya. Silahkan di next untuk lanjut ke Bagian 3! πŸ”₯

Bagian 3: Backend API dengan Node.js + Express

Halo sobat ruanginformatika! πŸ‘‹

Kita udah selesai bikin tampilan depan aplikasi to-do list pakai React dan Tailwind. Sekarang saatnya kita ngebangun backend-nya menggunakan Node.js + Express, dan tentu aja kita juga bakal sambungin ke database MongoDB.

πŸ“¦ Langkah 1: Inisialisasi Proyek Backend

Masuk ke direktori utama proyek dan buat folder baru untuk server:

mkdir server
cd server
npm init -y

Install dependensi utama:

npm install express mongoose dotenv cors

Tambahkan juga package untuk development:

npm install --save-dev nodemon

Edit file package.json dan tambahkan script:


"scripts": {
  "dev": "nodemon index.js"
}
  

🌐 Langkah 2: Setup Express Server

Buat file index.js di root folder server:


const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
require('dotenv').config();

const app = express();
const PORT = process.env.PORT || 5000;

app.use(cors());
app.use(express.json());

app.get('/', (req, res) => {
  res.send('API berjalan dengan baik πŸ‘');
});

mongoose.connect(process.env.MONGO_URI)
  .then(() => {
    app.listen(PORT, () => {
      console.log(`Server jalan di http://localhost:${PORT}`);
    });
  })
  .catch((err) => console.log(err));
  

πŸ” Langkah 3: Menyambungkan MongoDB

Daftar akun di MongoDB Atlas (kalau belum punya), lalu buat cluster gratis dan database baru.

Setelah itu, buat file .env:

MONGO_URI=isi_dengan_uri_mongodb_kamu

Pastikan file .env masuk ke .gitignore agar tidak ke-upload ke GitHub.

πŸ“„ Langkah 4: Membuat Model To-do

Buat folder models dan file Todo.js:


const mongoose = require('mongoose');

const todoSchema = new mongoose.Schema({
  title: {
    type: String,
    required: true
  },
  completed: {
    type: Boolean,
    default: false
  }
}, { timestamps: true });

module.exports = mongoose.model('Todo', todoSchema);
  

πŸ› οΈ Langkah 5: Membuat API CRUD

Buat folder routes dan file todoRoutes.js:


const express = require('express');
const router = express.Router();
const Todo = require('../models/Todo');

// Ambil semua todo
router.get('/', async (req, res) => {
  const todos = await Todo.find();
  res.json(todos);
});

// Tambah todo baru
router.post('/', async (req, res) => {
  const newTodo = new Todo({ title: req.body.title });
  const saved = await newTodo.save();
  res.json(saved);
});

// Hapus todo
router.delete('/:id', async (req, res) => {
  await Todo.findByIdAndDelete(req.params.id);
  res.json({ message: 'Todo dihapus' });
});

// Toggle status selesai
router.put('/:id', async (req, res) => {
  const updated = await Todo.findByIdAndUpdate(
    req.params.id,
    { completed: req.body.completed },
    { new: true }
  );
  res.json(updated);
});

module.exports = router;
  

Lalu import route ini di index.js:


const todoRoutes = require('./routes/todoRoutes');
app.use('/api/todos', todoRoutes);
  

βœ… Tes API

Gunakan Postman atau Thunder Client (VS Code extension) untuk mengetes endpoint:

  • GET /api/todos
  • POST /api/todos dengan body: { "title": "Belajar coding" }
  • DELETE /api/todos/:id
  • PUT /api/todos/:id dengan body: { "completed": true }

πŸš€ Kesimpulan

Sampai di sini, kita sudah:

  • Setup server dengan Express
  • Sambungkan ke database MongoDB
  • Buat model dan endpoint API dasar

Di artikel berikutnya, kita akan belajar membuat fitur login & register user menggunakan JWT πŸ”.

Jangan lupa push proyek kamu ke GitHub dan simpan baik-baik file .env-nya. Silahkan next page untuk ke Bagian 4!

Bagian 4: Autentikasi User dengan JWT

Halo teman-teman! πŸ‘‹

Di artikel sebelumnya, kita udah bikin backend API untuk CRUD data to-do. Tapi saat ini semua orang bisa akses tanpa login 😱. Jadi, di bagian ini kita bakal bikin sistem autentikasi user pakai JWT (JSON Web Token) di Express.

🧱 Langkah 1: Buat Model User

Buat file baru models/User.js:


const mongoose = require('mongoose');

const userSchema = new mongoose.Schema({
  email: { type: String, required: true, unique: true },
  password: { type: String, required: true }
}, { timestamps: true });

module.exports = mongoose.model('User', userSchema);
  

πŸ” Langkah 2: Setup Route Auth

Install dua package penting untuk enkripsi dan token:

npm install bcryptjs jsonwebtoken

Buat file routes/authRoutes.js:


const express = require('express');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const User = require('../models/User');
const router = express.Router();

// Register
router.post('/register', async (req, res) => {
  try {
    const { email, password } = req.body;
    const exist = await User.findOne({ email });
    if (exist) return res.status(400).json({ message: 'Email sudah terdaftar' });

    const hashed = await bcrypt.hash(password, 10);
    const newUser = new User({ email, password: hashed });
    await newUser.save();
    res.json({ message: 'User berhasil dibuat' });
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

// Login
router.post('/login', async (req, res) => {
  try {
    const { email, password } = req.body;
    const user = await User.findOne({ email });
    if (!user) return res.status(400).json({ message: 'Email tidak ditemukan' });

    const match = await bcrypt.compare(password, user.password);
    if (!match) return res.status(400).json({ message: 'Password salah' });

    const token = jwt.sign({ userId: user._id }, process.env.JWT_SECRET, { expiresIn: '7d' });
    res.json({ token });
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

module.exports = router;
  

Tambahkan route ini di index.js:


const authRoutes = require('./routes/authRoutes');
app.use('/api/auth', authRoutes);
  

πŸ›‘οΈ Langkah 3: Middleware Proteksi JWT

Buat file middleware/authMiddleware.js:


const jwt = require('jsonwebtoken');

function authMiddleware(req, res, next) {
  const token = req.header('Authorization')?.split(' ')[1];
  if (!token) return res.status(401).json({ message: 'Token tidak ada' });

  try {
    const verified = jwt.verify(token, process.env.JWT_SECRET);
    req.user = verified;
    next();
  } catch (err) {
    res.status(401).json({ message: 'Token tidak valid' });
  }
}

module.exports = authMiddleware;
  

Di route to-do, import middleware ini dan gunakan:


const auth = require('../middleware/authMiddleware');
router.get('/', auth, async (req, res) => {
  // hanya user yang sudah login bisa akses
});
  

πŸ§ͺ Langkah 4: Tes API Auth

Kamu bisa tes pakai Postman atau Thunder Client:

  • POST /api/auth/register β€” body: { “email”: “tes@mail.com”, “password”: “123456” }
  • POST /api/auth/login β€” dapatkan token
  • Gunakan token di header: Authorization: Bearer <token> saat akses todo

⚠️ Catatan

  • Jangan lupa buat JWT_SECRET di file .env:
JWT_SECRET=rahasia_super_aman

Gunakan string acak dan jangan bagikan token secara sembarangan.

βœ… Kesimpulan

Sekarang kita sudah punya sistem login dan register yang aman! Di artikel selanjutnya, kita akan sambungkan frontend dengan backend supaya user bisa login langsung dari React dan melihat to-do mereka masing-masing.

Sampai ketemu di Bagian 5: Menghubungkan Frontend dan Backend ya! πŸ”

Bagian 5: Menghubungkan Frontend dan Backend

Halo sobat ruanginformatika! πŸ‘‹

Sekarang kita sudah punya frontend dan backend yang masing-masing berjalan sendiri. Saatnya kita sambungkan keduanya agar user bisa login, melihat todo miliknya, dan mengelola data lewat UI React.

πŸ”§ Persiapan: Setup Proxy

Agar request ke server backend lebih simpel, tambahkan proxy di file client/package.json:

"proxy": "http://localhost:5000",

πŸ§‘β€πŸ’» Membuat Form Login dan Register

Buat komponen Login.jsx dan Register.jsx di folder client/src/pages:

Contoh: Register.jsx


import { useState } from 'react';
import axios from 'axios';

function Register() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const handleRegister = async (e) => {
    e.preventDefault();
    try {
      await axios.post('/api/auth/register', { email, password });
      alert('Registrasi berhasil! Silakan login.');
    } catch (err) {
      alert(err.response.data.message || 'Registrasi gagal');
    }
  };

  return (
    <form onSubmit={handleRegister}>
      <input type="email" value={email} onChange={e => setEmail(e.target.value)} placeholder="Email" />
      <input type="password" value={password} onChange={e => setPassword(e.target.value)} placeholder="Password" />
      <button type="submit">Daftar</button>
    </form>
  );
}

export default Register;
  

πŸ” Menyimpan dan Menggunakan Token

Saat login berhasil, simpan token ke localStorage:


const res = await axios.post('/api/auth/login', { email, password });
localStorage.setItem('token', res.data.token);
  

Buat instance axios dengan token:


const token = localStorage.getItem('token');
const api = axios.create({
  baseURL: '/',
  headers: {
    Authorization: `Bearer ${token}`
  }
});
  

πŸ“„ Menampilkan To-do dari User

Gunakan instance api untuk ambil to-do:


useEffect(() => {
  api.get('/api/todos')
    .then(res => setTodos(res.data))
    .catch(err => {
      if (err.response.status === 401) {
        alert('Silakan login terlebih dahulu');
      }
    });
}, []);
  

🌍 Routing Dasar

Gunakan react-router-dom untuk navigasi antar halaman:


import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Login from './pages/Login';
import Register from './pages/Register';
import Home from './pages/Home';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/login" element={<Login />} />
        <Route path="/register" element={<Register />} />
      </Routes>
    </BrowserRouter>
  );
}

export default App;
  

βœ… Kesimpulan

Di bagian ini, kita berhasil menghubungkan frontend dan backend dengan alur:

  • User daftar dan login dari React
  • Token disimpan di localStorage
  • React mengambil to-do milik user dari backend

Untuk versi lanjutan, kamu bisa tambahkan fitur seperti logout, validasi form, atau bahkan refresh token.

Di Bagian 6, kita akan deploy aplikasi ini ke internet (frontend dan backend). Klik next page untuk ke Bagian 6! πŸš€

Bagian 6: Deploy Aplikasi Todo ke Internet

Halo para developer! πŸ‘‹

Setelah kita membangun aplikasi todo lengkap dari frontend hingga backend, saatnya kita online-kan agar bisa diakses siapa saja. Yuk kita deploy ke internet πŸš€

πŸ“¦ 1. Struktur Project

Pastikan struktur project kamu seperti ini:


/todo-app
β”‚
β”œβ”€β”€ client          ← React frontend
β”œβ”€β”€ models
β”œβ”€β”€ routes
β”œβ”€β”€ .env
β”œβ”€β”€ index.js        ← Entry point Express
β”œβ”€β”€ package.json
  

Frontend dan backend dalam satu folder ya, tapi kita akan deploy secara terpisah.

🌐 2. Deploy Backend ke Render

  1. Buat akun dan login ke Render.com
  2. Pilih menu New β†’ Web Service
  3. Hubungkan ke GitHub dan pilih repo backend-mu
  4. Isi konfigurasi:
  • Name: todo-backend
  • Build Command: npm install
  • Start Command: node index.js
  • Environment: Node

Lalu tambahkan Environment Variables:

  • MONGO_URI: (link MongoDB Atlas)
  • JWT_SECRET: rahasia kamu
  • PORT: 10000 atau biarkan kosong

Render akan otomatis build dan deploy. Kamu akan mendapatkan URL misalnya https://todo-api.onrender.com

🌍 3. Deploy Frontend ke Netlify

  1. Buat akun dan login ke Netlify
  2. Klik β€œAdd new site” β†’ β€œImport from Git”
  3. Pilih repo React frontend kamu (folder client)

Isi pengaturan:

  • Build command: npm run build
  • Publish directory: build

Set environment variable agar React tahu URL backend-nya:

  • REACT_APP_API_BASE: URL dari backend Render kamu

Di kode React, kamu ambil URL backend seperti ini:


const API = axios.create({
  baseURL: process.env.REACT_APP_API_BASE,
  headers: {
    Authorization: `Bearer ${localStorage.getItem('token')}`
  }
});
  

πŸ›  Tips Tambahan

  • Pastikan semua request dari React ke backend pakai HTTPS (Render dan Netlify sudah HTTPS)
  • Kalau butuh CORS di backend, install dan gunakan:

npm install cors

const cors = require('cors');
app.use(cors());
  

βœ… Selesai!

Selamat! πŸŽ‰ Kamu sudah berhasil deploy aplikasi todo ke internet. Sekarang kamu bisa share link-nya ke teman atau portofolio.

Apa selanjutnya?

Sekian seri membangun aplikasi to-do fullstack dari ruanginformatika.com. Semoga bermanfaat dan menginspirasi!


Ditulis oleh ruanginformatika.com

Leave a Reply

Your email address will not be published. Required fields are marked *

You might also like