Todo App Lengkap
Aplikasi todo list production-ready dengan reaktivitas, localStorage persistence, dan input handling.
app
localStorage
reactive
Buka Aplikasi
Aplikasi terbuka di tab baru dengan navigasi penuh.
todo-app/index.pjs
---
judul: "Todo App Pro"
todos: ["Belajar PromptJS","Buat aplikasi pertama","Deploy ke production"]
---
Gaya:
body
font-family: 'Inter', system-ui, -apple-system, sans-serif
margin: 0
min-height: 100vh
background: linear-gradient(135deg, #0f0c29 0%, #302b63 50%, #24243e 100%)
color: #e0e0e0
display: flex
align-items: center
justify-content: center
padding: 20px
.app-container
width: 100%
max-width: 520px
background: rgba(255,255,255,0.05)
backdrop-filter: blur(20px)
-webkit-backdrop-filter: blur(20px)
border: 1px solid rgba(255,255,255,0.1)
border-radius: 24px
padding: 36px
box-shadow: 0 25px 60px rgba(0,0,0,0.4)
.app-header
display: flex
align-items: center
justify-content: space-between
margin-bottom: 24px
.app-header h1
margin: 0
font-size: 1.5rem
font-weight: 800
background: linear-gradient(135deg, #7dd3fc, #d3b6e9)
-webkit-background-clip: text
-webkit-text-fill-color: transparent
background-clip: text
.badge
font-size: 0.75rem
font-weight: 700
padding: 4px 12px
border-radius: 999px
background: rgba(134,239,172,0.15)
color: #86efac
.input-row
display: flex
gap: 8px
margin-bottom: 24px
.input-row input
flex: 1
padding: 12px 16px
background: rgba(255,255,255,0.06)
border: 1px solid rgba(255,255,255,0.12)
border-radius: 12px
color: #e0e0e0
font-size: 0.95rem
outline: none
font-family: inherit
transition: border-color 0.15s
.input-row input:focus
border-color: #7dd3fc
box-shadow: 0 0 0 3px rgba(125,211,252,0.1)
.input-row input::placeholder
color: #475569
.input-row button
padding: 12px 22px
background: linear-gradient(135deg, #7dd3fc, #4f9ef7)
border: none
border-radius: 12px
color: #0f172a
font-weight: 700
font-size: 0.95rem
cursor: pointer
transition: opacity 0.15s
font-family: inherit
white-space: nowrap
.input-row button:hover
opacity: 0.9
.task-list
list-style: none
padding: 0
margin: 0 0 16px
display: grid
gap: 6px
.task-item
display: flex
align-items: center
gap: 10px
padding: 12px 16px
background: rgba(255,255,255,0.03)
border: 1px solid rgba(255,255,255,0.05)
border-radius: 12px
transition: all 0.15s
.task-item:hover
background: rgba(255,255,255,0.06)
.task-text
flex: 1
font-size: 0.95rem
color: #e0e0e0
word-break: break-word
.del-btn
background: none
border: 1px solid rgba(239,68,68,0.2)
color: #fca5a5
cursor: pointer
padding: 4px 10px
border-radius: 8px
font-size: 0.85rem
transition: all 0.15s
font-family: inherit
flex-shrink: 0
.del-btn:hover
background: rgba(239,68,68,0.1)
border-color: rgba(239,68,68,0.4)
.footer-stats
display: flex
align-items: center
justify-content: space-between
padding-top: 16px
border-top: 1px solid rgba(255,255,255,0.06)
.footer-stats .summary
font-size: 0.8rem
color: #64748b
.footer-stats .clear-btn
font-size: 0.8rem
background: none
border: none
color: #fca5a5
cursor: pointer
font-family: inherit
opacity: 0.7
transition: opacity 0.15s
.footer-stats .clear-btn:hover
opacity: 1
.empty-state
text-align: center
padding: 24px
color: #475569
font-size: 0.9rem
Halaman TodoApp:
data daftar = []
data tugas = ""
Ketika muat:
simpan $todos ke daftar
Buat div.app-container:
Buat div.app-header:
Buat h1: $judul
Buat span.badge: "PRO"
Buat div.input-row:
Buat masukan#task-input:
placeholder = "Apa yang ingin kamu kerjakan?"
on_diketik = simpan document.querySelector("#task-input").value ke tugas
Buat tombol#btn-tambah:
"➕ Tambah"
on_klik = tambahkan tugas ke daftar
Buat daftar.task-list:
Ulangi untuk item dari daftar:
Buat li.task-item:
Buat span.task-text: item
Buat tombol.del-btn:
"✕"
on_klik = hapus item dari daftar
Buat div.footer-stats:
Buat div.summary:
"📋 "
Saat daftar:
Buat span:
panjang(daftar)
Buat span:
" tugas"
Buat tombol.clear-btn:
"Bersihkan"
on_klik = simpan [] ke daftar