Aplikasi Catatan Pribadi dengan React JS (Studi Kasus: PrivyNote)
Aplikasi catatan pribadi berbasis web yang memungkinkan pengguna untuk menyimpan dan mengelola catatan secara aman, dengan fitur seperti autentikasi pengguna, penyimpanan lokal, dan antarmuka yang sederhana dan responsif. Aplikasi ini dibangun menggunakan React JS dan menawarkan pengalaman pengguna yang cepat dan efisien.
Project Type & Role
Pribadi & Coding
Platform
Web
Project Detail
Timeline: Des 2021 – Jan 2022
Team: Anggito Budhi Prasojo
Di era digital seperti sekarang, kebutuhan untuk mencatan ide, rencana, atau hal-hal penting secara cepat menjadi sangat penting. Banyak orang menggunakan aplikasi catatan pribadi karena sifatnya yang praktis dan dapat diakses dimana saja. Dalam konteks pengembangan web modern, membuat aplikasi catatan pribadi sendiri itu bukanlah hanya melatih kemampuan teknis, akan tetapi juga bisa menjadi contoh project React JS aplikasi catatan sederhana yang menarik untuk portofolio kita sebagai developer.
Pada project ini, saya akan membuat sebuah aplikasi bernama PrivyNote — aplikasi catatan pribadi berbasis web yang dikembangkan menggunakan React JS. Project ini bertujuan untuk memberikan gambaran nyata tentang cara membuat aplikasi catatan pribadi dengan React JS, mulai dari perancangan struktur komponen, pengelolaan state, hingga penerapan desain yang responsif menggunakan Tailwind CSS.
PrivyNote ini dirancang agar pengguna dapat menulis, mengedit, menghapus, dan mengarsipkan catatan secara efisien. Selain itu, tampilannya dibuat minimalis agar tetap nyaman digunakan baik di desktop maupun perangkat mobile. Dengan pendekatan ini, project ini bukan hanya berfungsi sebagai aplikasi catatan, tetapi juga sebagai contoh penerapan konsep Single Page Application (SPA) yang interaktif dan ringan.
Tools dan Teknologi yang Digunakan
Dalam proses pembuatan aplikasi PrivyNote, saya menggunakan beberapa tools dan teknologi utama yang mendukung pengembangan aplikasi berbasis React JS. Setiap alat dipilih agar memudahkan proses coding, meningkatkan performa aplikasi, serta menjaga tampilan agar tetap responsif dan modern.
-
React JS
Merupakan library JavaScript yang dikembangkan oleh Meta (Facebook, Instagram, WhatsApp, Threads) untuk membangun antarmuka pengguna (UI) yang interaktif dan dinamis. Dengan konsep komponen, React memungkinkan developer memecah aplikasi menjadi bagian-bagian kecil yang dapat digunakan kembali. Dalam project ini, React digunakan untuk:
- Membuat komponen seperti
NoteItem, AddNote, dan Filter - Mengelola data catatan menggunakan React Hooks (useState, useEffect)
- Menyimpan data pengguna secara lokal menggunakan localStorage
Hasilnya, aplikasi dapat berjalan cepat tanpa harus melakukan reload halaman setiap kali ada perubahan data.
- Membuat komponen seperti
-
Tailwind CSS v4 (untuk tampilan responsif)
Untuk mendesain tampilan aplikasi agar lebih responsif dan mudah disesuaikan, saya menggunakan Tailwind CSS — sebuah framework CSS berbasis utility-first. Dengan tailwind, setiap elemen dapat diberi gaya langsung di dalam className seperti:
<div className="flex flex-col items-center p-4 bg-white rounded-lg shadow-md">Keuntungan utama dari Tailwind CSS adalah:
- Desain lebih cepat tanpa harus membuat file CSS panjang
- Tampilan otomatis menyesuaikan ukuran layar (mobile, tablet, atau desktop)
- Konsisten dengan gaya modern dan minimalis
Bahkan Tailwind CSS v4 ini membuat proses styling jauh lebih cepat tanpa menulis stylesheet manual. Di tailwind v4, konfigurasinya lebih sederhana seperti:
- Tidak ada file
tailwind.config.js - Tidak ada PostCSS config manual
- Cukup tambahkan directives Tailwind di file CSS
-
Node.js & npm
Node.js digunakan untuk menjalankan react disisi pengembang, sedangkan npm (Node Package Manager) berfungsi untuk mengelola dependensi seperti Tailwind, PostCSS, dan Autoprefixer. Dengan perintah sederhana seperti:
npm install npm startDeveloper dapat mengatur seluruh konfigurasi proyek dan menjalankan aplikasi secara lokal untuk pengujian.
-
VS Code
Sebagai code editor pilihan utama untuk menulis dan mengelola kode. VS Code dipilih karena memiliki banyak ekstensi pendukung seperti ESLint, Prettier, dan Tailwind IntelliSense yang mempercepat proses development dan memastikan kualitas kode tetap konsisten.
-
Local Storage API
PrivyNote menggunakan Local Storage API untuk menyimpan data catatan langsung di browser tanpa server. Artinya, semua catatan pengguna akan tetap tersimpan meskipun halaman di-refresh. Pendekatan ini membuat aplikasi tetap ringan dan cocok sebagai contoh project React JS sederhana yang berfokus pada pengelolaan data lokal.
-
Browser (Chrome/Edge) untuk testing
Dengan kombinasi tools di atas, pengembangan aplikasi PrivyNote menjadi efisien, terstruktur, dan mudah untuk dikembangkan lebih lanjut — baik untuk kebutuhan pribadi maupun sebagai proyek portofolio React JS.
Struktur Folder & Arsitektur Project
Dalam membangun aplikasi PrivyNote, saya menggunakan struktur folder yang sederhana namun terorganisir agar proses pengembangan lebih efisien. Struktur ini mengikuti pola umum pada aplikasi react js, dimana setiap komponen dipisahkan berdasarkan fungsinya. Berikut tampilan struktur dasar folder project PrivyNote:
privynote/
│
├── node_modules/
├── public/
│ ├── index.html
│ ├── favicon.ico
│ └── manifest.json
│
├── src/
│ ├── components/
│ │ ├── AddNote.js
│ │ ├── Filter.js
│ │ └── NoteItem.js
│ │
│ ├── App.js
│ ├── index.js
│ ├── index.css ← berisi @tailwind directives v4
│ └── assets/
│ └── favicon.png
│
├── package.json
Penjelasan lengkapnya seperti ini:
-
Folder public/
Folder public berisi file statis yang akan digunakan oleh React saat membangun aplikasi. File terpenting di dalamnya adalah:
- index.html → file utama yang menjadi root dari aplikasi react
- favicon.ico → icon kecil yang biasanya muncul pada tab browser. Dalam project ini, favicon masih standar pakai logonya react, supaya fokus ke isinya saja, hehehe
- manifest.json → berisi metadata aplikasi jika ingin dijalankan dalam mode Progressive Web App (PWA)
-
Folder src/
Semua logika dan komponen aplikasi terdapat di folder src/ (source). Di sinilah inti aplikasi PrivyNote dikembangkan. Isi utamanya:
- apps.js → komponen utama yang mengatur seluruh alur aplikasi, termasuk menampilkan daftar catatan dan integrasi localStorage
- index.js→ titik masuk (entry point) react untuk merender aplikasi ke dalam index.html
- index.css → file utama untuk memuat konfigurasi tailwind css, memastikan tampilan UI responsif dan seragam
- assets/ → berisi file pendukung seperti favicon, gambar, atau logo aplikasi
-
Folder components/
Folder ini berisi seluruh komponen modular yang membentuk UI aplikasi. Setiap komponen memiliki tanggung jawab yang jelas dan dapat digunakan kembali.
- AddNote.js → menangani input pengguna untuk menambahkan catatan baru
- Filter.js→ mengatur filter tampilan catatan (semua, aktif, arsip)
- NoteItem.js → menampilkan catatan dalam bentuk card disertai tombol edit, delete, dan arsip
Dengan pendekatan berbasis komponen ini, pengembangan aplikasi menjadi lebih mudah, dan setiap bagian UI dapat diperbarui tanpa mempengaruhi bagian lain.
-
File Konfigurasi
Beberapa file konfigurasi penting yang digunakan:
- package.json → mendefinisikan dependensi dari (React, Tailwind, PostCSS, dll) dan script seperti
npm startataunpm build
- package.json → mendefinisikan dependensi dari (React, Tailwind, PostCSS, dll) dan script seperti
Langkah-langkah Membuat Aplikasi Catatan Pribadi (PrivyNote) dengan React JS
Dalam bagian ini, kita akan membahas bagaimana cara membangun aplikasi PrivyNote dari nol menggunakan React JS dan Tailwind CSS v4. Langkah-langkah ini juga bisa digunakan untuk membuat aplikasi catatan sederhana lainnya, baik untuk portofolio pribadi maupun proyek pembelajaran frontend development.
-
Inisialisasi Project React
Langkah pertama adalah membuat project react baru menggunakan perintah:
npx create-react-app privynote cd privynotePerintah di atas akan membuat struktur folder dasar react lengkap dengan dependensi awal seperti ‘react, react-dom, dan react-scripts’. Setelah proses selesai, jalankan aplikasi untuk memastikan semuanya berfungsi:
npm startAplikasi default react akan berjalan di http://localhost:3000/.
-
Instalasi dan Konfigurasi Tailwind CSS v4
Agar tampilan PrivyNote lebih menarik dan responsif, kita menggunakan Tailwind CSS sebagai framework CSS. Instal dependensinya melalui terminal:
npm install tailwindcssSelanjutnya, tambahkan direktif Tailwind v4 ke dalam file src/index.css:
@import "tailwindcss";Sudah, hanya itu saja. Kita tidak membutuhkan:
- ❌ tailwind.config.js
- ❌ postcss.config.js
- ❌ @tailwind base
- ❌ @tailwind utilities
- ❌ @tailwind components
Itu tailwind versi lama (v3), kalo kalian tulis setup tersebut PASTI ERROR.
Setelah semua langkah di atas, jalankan kembali project dengan npm start dan pastikan style Tailwind sudah aktif di browser ya.
-
Membuat Komponen Utama
Masuk ke pondasi utamanya nih sob, PrivyNote akan dibangun menggunakan arsitektur berbasis komponen, di mana setiap bagian UI memiliki fungsinya sendiri.
-
AddNote.js (Form Tambah Catatan)
Komponen ini berfungsi untuk menambahkan catatan baru. User dapat mengetik judul dan isi catatannya lalu disimpan. Komponen ini digunakan untuk menambah catatan baru dengan judul dan isi.
import React, { useState } from "react"; const AddNote = ({ addNote }) => { const [title, setTitle] = useState(""); const [body, setBody] = useState(""); const handleSubmit = (e) => { e.preventDefault(); if (!title || !body) return; addNote(title, body); setTitle(""); setBody(""); }; return ( <form onSubmit={handleSubmit} className="add-note-form"> <input type="text" placeholder="Judul catatan..." value={title} maxLength={50} onChange={(e) => setTitle(e.target.value)} /> <textarea placeholder="Isi catatan Anda..." value={body} onChange={(e) => setBody(e.target.value)} ></textarea> <button type="submit">Simpan catatan</button> </form> ); }; export default AddNote; -
NoteItem.js
Menampilkan catatan dalam bentuk card. Tiap catatan memiliki tombol yang berbeda Edit, Delete, dan Arsipkan. Untuk menampilkan komponen ini, maka memerlukan setup berikut.
import React, { useState } from "react"; const NoteItem = ({ note, toggleArchive, deleteNote, editNote }) => { const [isEditing, setIsEditing] = useState(false); const [newTitle, setNewTitle] = useState(note.title); const [newBody, setNewBody] = useState(note.body); const handleSave = () => { editNote(note.id, newTitle, newBody); setIsEditing(false); }; return ( <div className="note-card"> {isEditing ? ( <div className="flex flex-col gap-2"> <input type="text" className="border rounded-lg p-2 focus:outline-none focus:ring-2 focus:ring-blue-500" value={newTitle} onChange={(e) => setNewTitle(e.target.value)} /> <textarea className="border rounded-lg p-2 h-24 resize-none focus:outline-none focus:ring-2 focus:ring-blue-500" value={newBody} onChange={(e) => setNewBody(e.target.value)} ></textarea> <button className="bg-blue-600 text-white rounded-lg px-3 py-2 hover:bg-blue-700 transition" onClick={handleSave} > Save </button> </div> ) : ( <div className="flex flex-col gap-2"> <h3 className="font-semibold text-lg">{note.title}</h3> <small className="text-gray-500 text-sm">{note.date}</small> <p className="text-gray-700 text-sm">{note.body}</p> <div className="actions flex gap-2 mt-2"> <button className="bg-red-500 text-white px-3 py-1 rounded-lg hover:bg-red-600 transition" onClick={() => deleteNote(note.id)} > Delete </button> <button className="bg-yellow-500 text-white px-3 py-1 rounded-lg hover:bg-yellow-600 transition" onClick={() => setIsEditing(true)} > Edit </button> <button className={`${ note.archived ? "bg-green-600" : "bg-gray-600" } text-white px-3 py-1 rounded-lg hover:opacity-80 transition`} onClick={() => toggleArchive(note.id)} > {note.archived ? "Unarchive" : "Archive"} </button> </div> </div> )} </div> ); }; export default NoteItem; -
Filter.js
Memungkinkan pengguna menyaring catatan berdasarkan status: aktif, diarsipkan, atau semua (ALL). Komponen filter untuk memilih tampilan catatan aktif, arsip, atau All.
// Filter.js import React from "react"; const Filter = ({ setFilter }) => { return ( <div className="filter"> <button onClick={() => setFilter("all")}>All Notes</button> <button onClick={() => setFilter("active")}>Active Notes</button> <button onClick={() => setFilter("archived")}>Archived Notes</button> </div> ); }; export default Filter; -
App.js (Pusat Logika PrivyNote)
Komponen utama yang mengatur seluruh alur aplikasi, mengelola state notes, filter, dan search, serta menyimpan data ke localStorage agar tidak hilang saat browser di-refresh. Komponen utama yang mengatur seluruh logika aplikasi, mulai dari: membuat catatan, edit catatan, delete catatan, mengarsipkan/unarchive, dll. Lengkapnya seperti ini.
import React, { useState, useEffect } from "react"; import NoteItem from "./NoteItem"; import AddNote from "./AddNote"; import Filter from "./Filter"; function App() { const [notes, setNotes] = useState([]); const [filter, setFilter] = useState("all"); const [search, setSearch] = useState(""); useEffect(() => { const savedNotes = JSON.parse(localStorage.getItem("notes")); if (savedNotes) setNotes(savedNotes); }, []); useEffect(() => { localStorage.setItem("notes", JSON.stringify(notes)); }, [notes]); const addNote = (title, body) => { const newNote = { id: Date.now(), title, body, date: new Date().toLocaleDateString("id-ID", { weekday: "long", day: "numeric", month: "long", year: "numeric", }), archived: false, }; setNotes([newNote, ...notes]); }; const toggleArchive = (id) => { const updated = notes.map((note) => note.id === id ? { ...note, archived: !note.archived } : note ); setNotes(updated); }; const deleteNote = (id) => { const filtered = notes.filter((note) => note.id !== id); setNotes(filtered); }; const editNote = (id, newTitle, newBody) => { const updated = notes.map((note) => note.id === id ? { ...note, title: newTitle, body: newBody } : note ); setNotes(updated); }; const filteredNotes = notes .filter((note) => { if (filter === "archived") return note.archived; if (filter === "active") return !note.archived; return true; }) .filter((note) => note.title.toLowerCase().includes(search.toLowerCase())); return ( <div className="note-app min-h-screen bg-gray-100 p-4"> <div className="max-w-screen-lg mx-auto"> <h1 className="text-2xl font-bold mb-4 text-center">Catatan Pribadi</h1> {/* Form Tambah Catatan */} <AddNote addNote={addNote} /> {/* Search */} <input type="text" placeholder="Cari catatan..." value={search} onChange={(e) => setSearch(e.target.value)} /> {/* Filter */} <Filter setFilter={setFilter} /> <div className="note-section mt-6"> <h2 className="note-title text-xl font-semibold mb-2"> Daftar Catatan </h2> {filteredNotes.length === 0 ? ( <p className="empty-msg">Belum ada catatan pada kategori ini.</p> ) : ( <div className="note-list grid gap-4 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-3"> {filteredNotes.map((note) => ( <NoteItem key={note.id} note={note} toggleArchive={toggleArchive} deleteNote={deleteNote} editNote={editNote} /> ))} </div> )} </div> </div> </div> ); } export default App;
-
Hasil Akhir Project: PrivyNote
Setelah seluruh komponen dan logika aplikasi dibangun, PrivyNote kini menjadi sebuah aplikasi catatan pribadi yang berfungsi penuh, responsif, dan mudah digunakan. Aplikasi ini dapat digunakan untuk membuat catatan harian, menyimpan ide penting, hingga mengelola daftar pekerjaan sederhana.
Berikut ini gambaran menyeluruh mengenai hasil akhir aplikasi PrivyNote.
1 Tampilan UI Modern dan Minimalis
PrivyNote menggunakan Tailwind CSS v4, yang membuat tampilan aplikasi menjadi:
Setiap elemen—mulai dari card catatan, form input, hingga tombol aksi menggunakan class tailwind sehingga tampilan modern langsung tercipta tanpa styling manual yang rumit.
UI akhir PrivyNote meliputi:
- Form tambah catatan dengan input judul dan isi catatan
- Daftar catatan dalam bentuk grid layout
- Tombol filter kategori (semua, aktif, arsip)
- Tombol aksi: edit, delete, Archive/Unarchive
2. CRUD Catatan Bekerja dengan Baik (Create, Read, Update, Delete)
Seluruh fungsi dasar yang dibutuhkan sebuah aplikasi note sudah bekerja dengan baik:
3. Fitur Arsip Catatan (Archive System)
PrivyNote menyediakan kemampuan untuk memindahkan catatan ke dalam kategori arsip. Ini berguna untuk pengguna yang ingin menyimpan catatan lama tanpa menghapusnya.
- Catatan aktif → dapat diarsipkan
- Catatan arsip → dapat di-unarchive kembali
4. Fitur Filter Catatan
Untuk mempermudah manajemen catatan, PrivyNote mendukung filter tampilan:
- All Notes → menampilkan seluruh data catatan
- Active Notes → menampilkan catatan yang belum diarsipkan
- Archived Notes → hanya catatan yang sudah dipindah ke arsip
Filter ini bekerja secara real-time tanpa reload halaman. Contoh hasilnya.
5. Tampilan Mobile
PrivyNote mendukung full responsive design, sehingga pengguna tetap nyaman mengakses aplikasi melalui smartphone. Dengan dukungan tampilan mobile ini, pengguna bisa mencatat ide kapan saja.
Penutup
PrivyNote bukan hanya berfungsi sebagai aplikasi untuk mencatat ide harian, tetapi juga sebagai project portofolio yang memperlihatkan kemampuan/skill kita dalam development. Ke depannya, aplikasi ini masih sangat bisa dikembangkan. Seperti itu saja yaa sob. Semoga catatan project saya ini membantu dan bermanfaat.