Akses kelas selamanya

Ambil Promo
flash sale
hamburger-menu

Tips All

Meningkatkan skills menjadi 1% lebih baik

Reset
Kelas Membuat Video Player Youtube Custom dengan Plyr.io di BuildWithAngga

Membuat Video Player Youtube Custom dengan Plyr.io

Di tutorial kali ini, kita akan membahas cara membuat video player Youtube custom menggunakan **Plyr.io,** sebuah library ringan dan responsif yang mendukung berbagai jenis media seperti Youtube, Vimeo, HTML5 Video. Kita juga akan mengkombinasikannya dengan Tailwind CSS untuk tampilan yang modern dan fleksibel di berbagai ukuran layar. Tujuan Preview Kita akan slicing section Youtube player dengan : Tampilan responsif dan roundedTombol play tengah custom (menggunakan ikon SVG sendiri)Poster video customKontrol terbatas : Play, Progres, Mute, Fullscreen Struktur HTML <div class="max-w-[321.61px] h-[227.9px] md:max-w-[522px] md:h-[369.9px] lg:max-w-[635.04px] lg:h-[450px] relative flex items-center justify-center"> <div id="Video" class="flex w-[321.61px] h-[227.9px] md:w-[522px] md:h-[369.9px] lg:w-[635.04px] lg:h-[450px] object-cover shrink-0 rounded-[20.26px] md:rounded-[32.88px] lg:rounded-[40px] overflow-hidden"> <div id="player" data-plyr-provider="youtube" data-plyr-embed-id="bTqVqk7FSmY"></div> </div> </div> Container bersifat responsif menyesuaikan ukuran layar.Elemen dengan id="player" adalah target untuk player Youtube dari PlyrKamu bisa mengganti data-plyr-embed-id dengan ID video Youtube yang lain. Inisialisasi Plyr di JavaScript Buat file videoPlay.js dan isi dengan : const player = new Plyr("#player", { controls: ["progress", "mute", "fullscreen", "play-large"], }); Ini mengatur kontrol yang ditampilkan : Progres bar, Tombol Mute, Fullscreen dan tombol play di tengah. Styling Custom dengan CSS Tambahkan CSS berikut agar tampilan lebih elegan dan sesuai dengan branding : /* Tombol play tengah */ .plyr__control--overlaid { background: none !important; border: none !important; box-shadow: none !important; } .plyr__control--overlaid::before { content: ""; display: block; width: 50px; height: 50px; background-image: url("assets/images/icons/play-button.svg"); background-size: contain; background-repeat: no-repeat; background-position: center; } @media (min-width: 834px) { .plyr__control--overlaid::before { width: 70px; height: 70px; } } /* Sembunyikan icon default */ .plyr button[data-plyr="play"] svg { display: none; } /* Hapus efek hover mute & fullscreen */ .plyr__controls button[data-plyr="mute"]:hover, .plyr__controls button[data-plyr="fullscreen"]:hover { background: transparent !important; box-shadow: none !important; filter: none !important; } /* Ganti poster video */ .plyr__poster { background-image: url("assets/images/thumbnails/thumbnail-video.png") !important; background-size: cover !important; background-position: center; } Menghilangkan background, border, dan bayangan dari tombol play bawaan yang muncul di tengah video saat belum diputar.Menambahkan ikon play custom di tengah video sebagai ::before dari tombol.Gambar ikon diambil dari assets/images/icons/play-button.svg.Ukuran ikon play jadi lebih besar di layar yang lebih lebar (desktop/tablet).Menyembunyikan ikon SVG play default dari Plyr biar nggak tumpang tindih sama ikon custom.Menghapus efek hover pada tombol mute dan fullscreenMengganti poster video (gambar thumbnail sebelum play) dengan gambar custom.Gambar diambil dari assets/images/thumbnails/thumbnail-video.png.Gambar diset untuk cover penuh area video dan posisi tengah. Sertakan Library Plyr Letakkan di <head> dan sebelum penutup </body> HTML : <-- Di tag Head --> <link rel="stylesheet" href="<https://cdn.plyr.io/3.7.8/plyr.css>" /> <-- Sebelum Penutup --> <script src="<https://cdn.plyr.io/3.7.8/plyr.js>"></script> <script src="js/videoPlay.js"></script> Penutup Kalau kamu ingin membuat pemutar video YouTube yang lebih menarik dan enak dipakai di website-mu, Plyr.io adalah pilihan yang tepat. Caranya mudah, fiturnya lengkap, dan hasilnya lebih profesional daripada pemutar YouTube biasa.

Kelas Slicing Desain “Empty State Airplane” dari Figma ke HTML, Tailwind CSS dan JavaScript di VSCode di BuildWithAngga

Slicing Desain “Empty State Airplane” dari Figma ke HTML, Tailwind CSS dan JavaScript di VSCode

Daftar Isi Latar BelakangTujuan ArtikelTarget PembacaSetelah MembacaDownload DesainMembuat Akun FigmaImport ke FigmaMembaca DesainDi Bagian ini Kamu Akan Bisa :Shortcut KeyboardMembaca IconMembaca GambarMembaca LayoutMemulai SlicingDi Bagian ini Kamu Akan Bisa :Buka Folder SebelumnyaStarterSlicing 1Slicing 2Slicing 3Slicing 4Slicing 5Slicing 6Slicing 7Slicing 8Slicing 9Slicing 10Slicing 11Slicing 12Penutup Latar Belakang Dalam era pengembangan mobile-first, desain antarmuka harus dioptimalkan untuk layar kecil (maksimal 640px) dengan presisi pixel-perfect. Figma memungkinkan desainer membuat mockup mobile yang akurat, sementara Tailwind CSS menawarkan fleksibilitas untuk menerjemahkan desain tersebut ke kode yang responsif. Namun, tantangan utama muncul ketika: Akurasi Visual: Menyamakan setiap elemen desain (spasi, ukuran, posisi) di Figma dengan implementasi kode hingga ke level piksel, termasuk penyesuaian konfigurasi Tailwind untuk hardcoded values (misal: w-[320px], gap-3.5).Responsivitas Terkontrol: Mempertahankan batas lebar 640px sebagai breakpoint utama sambil memastikan komponen tetap konsisten di semua perangkat mobile (misal: menggunakan max-w-[640px] mx-auto).Optimasi untuk Mobile: Menghindari over-engineering dengan memanfaatkan utility class Tailwind yang sesuai untuk viewport kecil (misal: padding, font-size, grid layout).Interaktivitas Mobile-First: Implementasi JavaScript untuk interaksi touch-friendly (seperti klik, swipe) yang tetap presisi sesuai desain Figma. Artikel ini menyajikan pendekatan sistematis untuk slicing desain Figma mobile-first ke kode HTML, Tailwind CSS, dan JavaScript di VSCode, dengan fokus pada ketelitian pixel-perfect dan optimasi performa mobile. Tujuan Artikel Artikel ini bertujuan untuk: Memberikan Panduan Praktis: Menunjukkan langkah demi langkah cara menerjemahkan desain Empty State Airplane dari Figma ke struktur HTML + Tailwind CSS dengan akurasi pixel-perfect.Mengoptimalkan untuk Mobile: Menyusun komponen dengan pendekatan mobile-first, menjaga konsistensi lebar, padding, margin, dan skala font sesuai dengan batas maksimal 640px.Menerapkan Tailwind CSS secara Efisien: Menggunakan utility classes Tailwind, termasuk pendekatan hardcoded values (seperti w-[320px], gap-3.5), untuk mencapai kesetiaan desain maksimal tanpa over-engineering.Meningkatkan Presisi Visual: Menggunakan teknik inspeksi dan pengukuran langsung di Figma untuk memastikan setiap elemen (ikon, ilustrasi, teks, spasi) direplikasi secara akurat.Mengintegrasikan Interaktivitas Ringan: Menambahkan fungsionalitas sederhana menggunakan JavaScript berbasis sentuhan (touch-friendly interaction), tanpa mengorbankan performa untuk perangkat mobile. Dengan mengikuti panduan ini, pembaca dapat memahami bagaimana mengubah desain Figma mobile menjadi kode nyata yang responsif, presisi, dan optimal untuk mobile device. Target Pembaca Artikel ini ditujukan bagi: Frontend Developer yang sering bekerja dengan desain Figma dan ingin meningkatkan presisi implementasi desain mobile.UI Engineer yang fokus pada pixel-perfect implementation dan ingin memahami praktik terbaik konversi desain ke Tailwind CSS.Desainer yang Belajar Coding dan ingin tahu bagaimana desain mereka diimplementasikan dalam kode dengan konsistensi visual di perangkat kecil.Mahasiswa / Pembelajar Web Development yang ingin menambah portofolio dengan praktik langsung slicing desain Figma mobile-first menggunakan Tailwind CSS di lingkungan kerja nyata (VSCode).Tim Pengembang Mobile Web yang ingin menyusun guideline konversi desain ke HTML+CSS yang efisien dan terstandarisasi. Dengan gaya penulisan yang teknis namun aplikatif, artikel ini cocok bagi mereka yang ingin meningkatkan workflow antara desain dan kode, terutama dalam konteks proyek berbasis Tailwind CSS dan pendekatan mobile-first. Setelah Membaca Setelah membaca artikel ini, pembaca diharapkan mampu: Melakukan Slicing Desain Mobile: Mengubah desain Figma untuk layar kecil (≤640px) menjadi struktur HTML + Tailwind CSS yang pixel-perfect.Menggunakan Tailwind dengan Presisi: Memanfaatkan utility class bawaan dan custom value (seperti w-[320px], gap-3.5) untuk meniru ukuran dan spasi desain secara akurat.Membangun Layout Mobile-First yang Konsisten: Membuat layout yang responsive namun tetap mempertahankan batas maksimal 640px, menggunakan prinsip mobile-first development.Mengoptimalkan Performa Mobile: Menulis kode HTML, CSS, dan JavaScript yang ringan, cepat dimuat, dan responsif terhadap interaksi berbasis sentuhan.Mengembangkan Keterampilan Inspeksi Desain: Membaca, mengukur, dan memahami elemen-elemen di Figma dengan lebih teliti untuk memastikan hasil implementasi visual 1:1. Dengan keterampilan ini, pembaca akan lebih percaya diri dalam mengerjakan proyek-proyek berbasis mobile dan dapat mempercepat alur kerja antara desain dan pengembangan. Download Desain Homepage Shaynakit Untuk mulai melakukan slicing desain Empty State Airplane, Kamu perlu mengunduh file desain Figma-nya terlebih dahulu. Desain ini tersedia secara gratis dalam mode Free Trial melalui situs ShaynaKit. Berikut adalah langkah-langkah lengkapnya: Buka situs utama ShaynaKit di https://shaynakit.com/landing.Klik menu atau tombol Register atau langsung buka https://shaynakit.com/register untuk membuat akun terlebih dahulu.Setelah berhasil mendaftar dan login, buka halaman desain yang akan digunakan di https://shaynakit.com/details/empty-state-airplane.Klik tombol Download, lalu pada opsi yang tersedia, pilih Free Trial.Klik tombol Start Today untuk memulai akses gratis.Setelah itu, kembali ke halaman yang sama: https://shaynakit.com/details/empty-state-airplane, dan klik tombol Download sekali lagi.File desain akan terunduh dalam format .fig, yaitu format asli file Figma.Simpan file .fig tersebut ke dalam folder lokal proyek Anda, misalnya ./figma/EmptyStateAirplane.fig. Membuat Akun Figma Homepage Figma Kunjungi Situs Figma : Buka browser lalu akses https://www.figma.com.Pilih “Sign up” atau “Get started for free” : Tombol ini biasanya ada di pojok kanan atas halaman utama.Masukkan Data RegistrasiEmail: Gunakan email aktif yang kamu miliki.Nama Lengkap: Nama ini akan tampil di kolaborasi.Password: Buat minimal 8 karakter, disarankan mencampur huruf dan angka.Verifikasi Email : Cek inbox email yang kamu daftarkan, klik link verifikasi dari Figma untuk mengaktifkan akun.Pilih Plan : Setelah verifikasi, Figma akan menawarkan beberapa plan (Free, Professional, Organization). Untuk memulai, cukup pilih Free.Selesai & Masuk ke Dashboards : Kamu akan diarahkan ke dashboard Figma, di mana kamu bisa membuat file baru, mengimpor file .fig, dan mengundang tim. Import ke Figma Working Folder Kunjungi Situs Figma. Buka browser lalu akses https://www.figma.com.Setelah masuk, kamu akan berada di tampilan utama Figma. Di sini kamu bisa melihat daftar file dan proyek sebelumnya.Klik tombol "Import File" (ikon ⬆️ di pojok kanan atas, atau menu File > Import).Arahkan ke lokasi file .fig yang telah kamu simpan sebelumnya (misalnya ./figma/EmptyStateAirplane.fig).Pilih file tersebut, lalu klik Open atau Import.Figma akan memproses file, dan setelah selesai, desain akan muncul sebagai proyek baru di dashboard Anda.Klik file tersebut untuk membukanya. Membaca Desain Di Bagian ini Kamu Akan Bisa : ✅ Figma Lebih Detail ✅ Sortcut Keyboard untuk Figma ✅ Membaca Icon ✅ Membaca Gambar ✅ Membaca Layout Shortcut Keyboard Copy Paste Berfungsi menggandakan desain. Bonus Saldo - Copy Paste Cara melakukannya : Pilih frame, grup, atau objek yang ingin digandakan. Bonus Saldo - Klik Tekan Ctrl + D (Windows) atau Cmd + D (Mac). Figma akan langsung membuat salinan tepat di bawah/kanan aslinya. Jika ingin membuat lebih dari satu, cukup tekan lagi Ctrl + D. Ctrl + Z Berfungsi untuk kembali 1 langkah sebelumnya. Bonus Saldo - Ctrl Z Cara melakukannya : Klik sekali di area canvas atau jendela file Figma supaya aplikasi menerima input keyboard.Windows/Linux: Tekan Ctrl + Z sekali untuk membatalkan (undo) satu perubahan terakhir.Mac: Tekan ⌘ Cmd + Z sekali untuk membatalkan satu perubahan terakhir. Ctrl + Shift + Z Berfungsi membatalkan “kembali 1 langkah sebelumnya”. Cara melakukannya : Klik sekali di area canvas atau jendela file Figma supaya aplikasi menerima input keyboard.Windows/Linux: Tekan Ctrl + Shift + Z untuk redo (maju kembali setelah undo).Mac: Tekan ⌘ Cmd + Shift + Z untuk redo (maju kembali setelah undo) Klik 2X Berfungsi untuk melihat size group yang kamu mau. Contoh ketika di “Deskripsi Judulnya” : Arahkan kursor ke group ( Title & Description ), hingga muncul garis biru seperti ini. Bonus Saldo - Teks Klik 2X pada “Deskripsinya” Bonus Saldo - Paragraf Perhatikan pada bilah kanan Figma terdapat konfigurasi teksnya. Bonus Saldo - Paragraf Sidebar Ulangi hal tersebut pada group desain apapun yang ingin kamu mau tau. Klik Beberapa Kali+ Hover + Alt Berfungsi melihat jarak antar konten desain, contohnya antar “Title dengan Paragraf” seperti : Bonus Saldo - Gap Teks Cara melakukannya : Arahkan kursor di atas “Paragrafnya”. Klik pada Deskripsi “We give you early credit so that you can buy a flight ticket” Beberapa Kali sampai seperti ini : Bonus Saldo - Paragraf Pindahkan cursor ke Title “Big Bonus”. Klik Alt. Maka akan muncul celah di antara keduanya yaitu ( 10 ) artinya 10px, hal ini berfungsi untuk development nanti. Bonus Saldo - Gap Teks Import Icon Menjadi SVG Berfungsi mengambil Icon lalu di letakkan di folder Icon VSCode lalu di tampilkan di browser. Cara Melakukannya : Klik beberapa kali di atas icon Figma hingga seperti ini ( 24 x 24 ) : Bonus Saldo - Airplane Icon Klik kanan. Bonus Saldo - Right of Click Kursor di atas “Copy/Paste as” dan klik “Copy as SVG”. Bonus Saldo - Import SVG Import Image menjadi PNG Klik di atas image Figma hingga seperti ini ( 299.96 x 150 ) : Success Checkout - Background Image Scroll ke bawah sampai seperti pada bilah kanan. Success Checkout - Import Background Image Klik dropdown “Export” nya bertulis “1x” : maka muncul : Pilih “3x” dan klik tombol “Export Basic Interview” Membaca Icon Icon Yang Mana? Bonus Saldo - Airplane Di atas adalah icon. Di dalam desain Figma, icon adalah elemen grafis kecil yang biasanya digunakan untuk mewakili aksi, fitur, atau objek tertentu dengan cara yang visual dan mudah dikenali. Di dalam desain Figma icon adalah : Gambar vektor kecil (SVG) atau bentuk (shapes) yang menggambarkan sesuatu, seperti 🔍 (search), ✏️ (edit), 🗑 (delete), dll.Sering digunakan dalam UI/UX design seperti di tombol, menu navigasi, tab, atau status indicator. Fungsi Icon adalah : Hemat ruang : Ikon menggantikan teks panjang agar antarmuka tetap ringkas.Estetika visual : Ikon bikin desain lebih menarik dan terasa hidup.Bahasa universal : Ikon mudah dipahami lintas bahasa misalnya ikon globe untuk "global".Representasi aksi : Misal ikon gerigi = pengaturan, amplop = pesan, dll. Cara Import? Berfungsi mengambil Icon lalu di letakkan di folder Icon VSCode lalu di tampilkan di browser. Cara Melakukannya : Klik beberapa kali di atas icon Figma hingga seperti ini ( 24 x 24 ) : Bonus Saldo - Airplane Klik kanan. Bonus Saldo - Airplane Click Kursor di atas “Copy/Paste as” dan klik “Copy as SVG”. Bonus Saldo - Airplane Click Import Buat folder proyek yaitu “Empty-State-Airplane” Folder Proyek Open folder tersebut di VSCode VS Code Proyek Buka VSCode.Klik File > Open Folder...Pilih folder project kamu, yaitu : Empty-State-Airplane.Setelah folder terbuka di sidebar kiri (Explorer), kamu bisa mulai membuat folder baru. Buat Folder src Src Folder Klik kanan pada folder utama Empty-State-Airplane di sidebar kiri.Pilih New Folder.Ketik nama folder: src, lalu tekan Enter. Buat Folder images di dalam src Images Folder Klik ikon > di samping src untuk membukanya.Klik kanan pada folder src > New Folder.Ketik nama folder: images, lalu tekan Enter. Buat Folder Tambahan di Dalam images Any Folder Klik ikon > di samping images untuk membukanya.Klik kanan pada folder images > New Folder.Buat folder berikut satu per satu:backgroundsicons Buat File airplane.svg di dalam folder icons untuk meletakkan iconnya Klik ikon > di samping icons untuk membukanya. Klik kanan pada folder icons > New File. Buat file bernama airplane.svg Klik link “Open file using VS Code’s standard text/binary editor?” Icon VSCode Ctrl + V disini Icon VSCode For Paste Hasil akhirnya akan seperti ini : Icon VSCode After Paste Membaca Gambar Gambar Yang Mana? Success Checkout - Background Image Image ini berfungsi : Menyampaikan Konten Nyata : Gambar background memberi gambaran visual “in‑context” tentang halaman yang hendak ditampilkan ke user.Membuat Prototipe Lebih Hidup : Daripada tanpa background image, menggunakan background image bikin stakeholder atau user test lebih paham feel UI. Cara Import? Berfungsi mengambil Icon lalu di letakkan di folder Icon VSCode lalu di tampilkan di browser. Cara Melakukannya : Klik di atas image Figma hingga seperti ini ( 299.96 x 150 ) : Success Checkout - Background Image Scroll ke bawah sampai seperti pada bilah kanan. Success Checkout - Sidebar Background Image Klik dropdown “Export” nya bertulis “1x” : maka muncul : Pilih “3x” dan klik tombol “Export Basic Interview” Letakkan ditempat yang kamu mau. Masuk ke proyek Empty-State-Airplane lalu masuk ke folder src/images/backgrounds. Drag image tersebut sampai begini. Success Checkout - After Import Background Image Membaca Layout Identifikasi Konten Desain Link Berpindah Halaman LInk berpindah halaman adalah bagian ketika user klik, user akan berpindah halaman satu ke halaman yang lain. Button Urutan A → B → C → dst Terbesar → besar → kecil → makin kecil → makin kecil -> dst Structure Basic Memulai Slicing Di Bagian ini Kamu Akan Bisa : ✅ Slicing dari Figma ke VSCode✅ Mahir Tailwind CSS✅ Pixel Perfect✅ Responsive max 640px Buka Folder Sebelumnya Folder Proyek Starter Jalankan perintah di terminal. npm install tailwindcss @tailwindcss/cli Penjelasan: PaketFungsitailwindcssMenginstal Tailwind CSS versi terbaru (saat ini versi 4), yaitu framework utility-first CSS.@tailwindcss/cliMenginstal CLI resmi dari Tailwind untuk membangun file CSS langsung dari terminal (tanpa perlu setup tambahan seperti PostCSS atau Webpack). Pada side bar VSCode di dalam folder src bikin file bernama input.css . Letakkan ini /* src/input.css */ @import "tailwindcss"; Lalu pada // package.json { "dependencies": { "@tailwindcss/cli": "^4.1.4", "tailwindcss": "^4.1.4" } } Beri kode seperti ini: // package.json { "scripts": { "dev": "npx @tailwindcss/cli -i ./src/input.css -o ./src/output.css --watch" }, "dependencies": { "@tailwindcss/cli": "^4.1.4", "tailwindcss": "^4.1.4" } } Penjelasan: BagianPenjelasan"scripts"Merupakan bagian dari package.json yang berisi perintah-perintah (alias) yang bisa kamu jalankan dengan npm run atau yarn."dev"Nama alias dari script ini. Kamu bisa menjalankannya dengan perintah npm run dev."npx @tailwindcss/cli"Menjalankan CLI Tailwind secara langsung tanpa perlu instal global.-i ./src/input.cssMengatur file input CSS. File ini harus berisi direktif seperti @tailwind base;, @tailwind components;, dan @tailwind utilities; tetapi tailwind 4 telah menuliskannya secara implisit.-o ./src/output.cssMengatur file output CSS yang akan dihasilkan oleh Tailwind (berisi semua utility class Tailwind yang digunakan di project).--watchMengaktifkan mode pemantauan. Tailwind akan terus memantau perubahan pada file HTML/JS/CSS yang kamu atur dan memperbarui output.css setiap kali ada perubahan. Buat file index.html di src/ . Letakkan html dasar di dalamnya. <!-- src/index.html --> <!doctype html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link href="./output.css" rel="stylesheet"> </head> <body> <h1 class="text-2xl font-semibold"> Hello world! </h1> </body> </html> Penjelasan: Baris HTMLPenjelasan<!doctype html>Mendeklarasikan bahwa dokumen ini adalah dokumen HTML5. Wajib di bagian paling atas.<html>Elemen root dari seluruh dokumen HTML. Semua elemen HTML berada di dalam tag ini.<head>Bagian yang berisi informasi meta (bukan tampilan), seperti encoding, viewport, stylesheet, dll.<meta charset="UTF-8">Menentukan karakter encoding sebagai UTF-8, sehingga bisa menampilkan karakter dari berbagai bahasa dengan benar.<meta name="viewport" content="width=device-width, initial-scale=1.0">Mengatur agar layout responsive di perangkat mobile dengan menyesuaikan lebar viewport.<link href="./output.css" rel="stylesheet">Menyertakan file CSS (output.css) yang dihasilkan oleh Tailwind agar dapat digunakan di HTML.<body>Bagian utama halaman yang berisi konten yang ditampilkan di browser.<h1 class="text-2xl font-semibold">Heading tingkat 1. Class text-2xl dan font-semibold dari Tailwind digunakan untuk mengatur ukuran dan ketebalan font.Hello world!Isi teks yang ditampilkan di halaman.</body> dan </html>Menutup elemen body dan html. Tambahkan font Poppins pada tag head html nya <!-- src/index.html --> <link href="<https://fonts.googleapis.com/css2?family=Poppins:wght@100;200;300;400;500;600;700;800;900&display=swap>" rel="stylesheet" /> Lalu tambahkan konfigurasi body seperti ini /* src/input.css */ body { font-family: "Poppins"; background-color: #DAE1E9; } Penjelasan: Utility CSSNilaiPenjelasanfont-family"Poppins"Mengatur jenis huruf utama pada elemen <body> menjadi Poppins.background-color#DAE1E9Memberikan warna latar belakang pada elemen <body> dengan warna abu kebiruan terang (kode hex #DAE1E9). Definisikan warna yang di pakai dalam desain seperti berikut di dalam input.css. /* src/input.css */ @theme { --color-empty-bg: #FAFAFA; --color-empty-black: #1F1449; --color-empty-grey: #9698A9; --color-empty-blue-card: #5445E5; --color-empty-shadow-card: #3F32B2; --color-empty-shadow-rounded: #998EFD; --color-empty-blue: #5C40CC; } Penjelasan: Variabel CSSNilai WarnaPenjelasan--color-empty-bg#FAFAFAWarna latar belakang yang sangat terang, hampir putih.--color-empty-black#1F1449Warna hitam keunguan gelap, biasanya untuk teks utama atau judul.--color-empty-grey#9698A9Warna abu-abu netral, cocok untuk teks sekunder atau placeholder.--color-empty-blue-card#5445E5Warna biru keunguan terang untuk elemen kartu utama.--color-empty-shadow-card#3F32B2Warna lebih gelap dari blue-card, kemungkinan untuk bayangan kartu.--color-empty-shadow-rounded#998EFDWarna ungu muda, bisa digunakan untuk efek shadow dengan radius membulat.--color-empty-blue#5C40CCWarna biru keunguan, cocok untuk elemen primer seperti tombol atau ikon. Slicing 1 Bonus Saldo - Container Mobile Tujuan Mendesain elemen dengan pendekatan mobile-first agar responsif, dengan lebar maksimum 640px dan posisi terpusat di layar. Code <body> <main class="relative mx-auto w-full max-w-[640px] overflow-hidden min-h-screen py-[151px] px-[37.5px] bg-empty-bg"></main> </body> Penjelasan Atribut/Utility CSSFungsirelativeMengatur posisi elemen relatif terhadap dirinya sendiri (untuk posisi absolut anaknya).mx-autoMembuat margin kiri dan kanan otomatis → memusatkan secara horizontal.w-fullMengatur lebar elemen 100% dari kontainer induknya.max-w-[640px]Membatasi lebar maksimum ke 640px.overflow-hiddenMenyembunyikan isi yang meluap di luar kontainer.min-h-screenMenetapkan tinggi minimum sama dengan tinggi layar (100vh).py-[151px]Padding vertikal (atas dan bawah) sebesar 151px.px-[37.5px]Padding horizontal (kiri dan kanan) sebesar 37.5px.bg-empty-bgMenggunakan warna latar belakang dari variabel tema --color-empty-bg. Slicing 2 Bonus Saldo - Child Container Mobile Tujuan Tag <form> ini digunakan untuk mengirim data dari pengguna ke halaman lain, yaitu success-checkout.html, ketika form dikirim (biasanya saat tombol submit ditekan). Code <main class="relative mx-auto w-full max-w-[640px] overflow-hidden min-h-screen py-[151px] px-[37.5px] bg-empty-bg"> <!-- dari sini --> <form action="success-checkout.html"></form> <!-- sampai sini --> </main> Penjelasan AtributNilaiPenjelasan<form>-Elemen HTML yang digunakan untuk membungkus input dan tombol agar bisa dikirim.action"success-checkout.html"Menentukan URL tujuan saat form disubmit. Dalam hal ini, browser akan membuka halaman success-checkout.html setelah submit. Slicing 3 Bonus Saldo - Container Bank Tujuan Elemen <section> ini digunakan untuk menampilkan sebuah kartu konten yang terstruktur secara vertikal, dengan jarak antar elemen, padding yang cukup, pojok membulat, warna latar belakang khusus, dan teks berwarna putih, serta siap menampung konten tambahan di dalamnya. Code <main class="relative mx-auto w-full max-w-[640px] overflow-hidden min-h-screen py-[151px] px-[37.5px] bg-empty-bg"> <form action="success-checkout.html"> <!-- dari sini --> <section id="Card" class="flex flex-col gap-[41px] p-6 rounded-[34px] relative bg-empty-blue-card text-white overflow-hidden"></section> <!-- sampai sini --> </form> </main> Penjelasan Atribut/Utility CSSPenjelasan<section>Elemen semantik untuk membungkus bagian tertentu dari konten.id="Card"Memberikan identitas unik agar bisa diakses lewat JavaScript atau anchor.flexMenjadikan kontainer sebagai flexbox (untuk tata letak fleksibel).flex-colMengatur arah tata letak flex ke kolom (vertikal).gap-[41px]Jarak antar anak elemen sebesar 41px.p-6Padding ke seluruh sisi sebesar 1.5rem (24px).rounded-[34px]Membuat sudut elemen melengkung sebesar 34px.relativePosisi relatif untuk pengaturan posisi anak dengan absolute.bg-empty-blue-cardMemberi warna latar belakang dari variabel --color-empty-blue-card.text-whiteWarna teks diatur menjadi putih.overflow-hiddenMenyembunyikan konten yang meluap dari batas elemen. Slicing 4 Bonus Saldo - Child 1 Container Bank Tujuan Untuk menampilkan informasi identitas pengguna (nama) di sebelah kiri dan indikator status atau tombol aksi pembayaran ("Pay") dengan ikon pesawat di sebelah kanan, dalam satu baris yang rapi dan sejajar. Code <main class="relative mx-auto w-full max-w-[640px] overflow-hidden min-h-screen py-[151px] px-[37.5px] bg-empty-bg"> <form action="success-checkout.html"> <section id="Card" class="flex flex-col gap-[41px] p-6 rounded-[34px] relative bg-empty-blue-card text-white overflow-hidden"> <!-- dari sini --> <div class="flex items-center justify-between relative z-20"> <div> <h2 class="font-light text-sm leading-[21px]">Name</h2> <p><strong class="font-medium text-xl leading-[30px]">Kezia Rifqi</strong></p> </div> <div class="flex items-center gap-[6px] shrink-0"> <img src="assets/images/icons/airplane.svg" alt="" class="size-6 shrink-0" /> <p class="font-medium">Pay</p> </div> </div> <!-- sampai sini --> </section> </form> </main> Penjelasan Atribut/Utility CSSPenjelasanflex items-center justify-betweenMenyusun elemen secara horizontal, sejajar secara vertikal, dan diberi ruang di antara (kiri-kanan).relative z-20Elemen diberi posisi relatif (untuk layering), dan z-index 20 agar muncul di atas elemen lain.h2.font-light text-sm leading-[21px]Teks "Name" berukuran kecil, tipis, dan tinggi baris 21px.strong.font-medium text-xl leading-[30px]Nama "Kezia Rifqi" tampil menonjol dengan font medium dan ukuran 30px.div.flex.items-center.gap-[6px]Menyusun ikon dan teks "Pay" secara horizontal dengan jarak 6px di antaranya.img.size-6Ikon pesawat dengan ukuran 1.5rem (24px × 24px).shrink-0Mencegah elemen (ikon dan kontainer kanan) mengecil saat ruang terbatas. Slicing 5 Bonus Saldo - Child 2 Container Bank Tujuan Bagian ini bertujuan untuk menampilkan saldo (balance) pengguna, dengan label "Balance" di atas dan nominal saldo yang ditampilkan secara mencolok dan mudah dibaca. Code <main class="relative mx-auto w-full max-w-[640px] overflow-hidden min-h-screen py-[151px] px-[37.5px] bg-empty-bg"> <form action="success-checkout.html"> <section id="Card" class="flex flex-col gap-[41px] p-6 rounded-[34px] relative bg-empty-blue-card text-white overflow-hidden"> <div class="flex items-center justify-between relative z-20"> <div> <h2 class="font-light text-sm leading-[21px]">Name</h2> <p><strong class="font-medium text-xl leading-[30px]">Kezia Rifqi</strong></p> </div> <div class="flex items-center gap-[6px] shrink-0"> <img src="assets/images/icons/airplane.svg" alt="" class="size-6 shrink-0" /> <p class="font-medium">Pay</p> </div> </div> <!-- dari sini --> <div class="relative z-20"> <h2 class="font-light text-sm leading-[21px]">Balance</h2> <p> <strong class="font-medium text-[26px] leading-[39px] break-words">IDR <span id="formatted-price">280000000</span></strong> </p> </div> <!-- sampai sini --> </section> </form> </main> <!-- dari sini --> <script src="./js/format-idr.js"></script> <!-- sampai sini --> JavaScript // ./js/format-idr.js let priceElement = document.getElementById("formatted-price"); let priceValue = parseInt(priceElement.textContent, 10); priceElement.textContent = new Intl.NumberFormat("id-ID", {currency: "IDR", minimumFractionDigits: 0, maximumFractionDigits: 0 }).format(priceValue); Penjelasan Elemen/Utility CSSPenjelasandiv.relative z-20Posisi relatif dan z-index: 20, memastikan elemen ini berada di atas lapisan lainnya.h2.font-light text-sm leading-[21px]Menampilkan label "Balance" dengan ukuran kecil dan font tipis.strong.font-medium text-[26px] leading-[39px]Menonjolkan jumlah saldo dengan ukuran font 26px dan tinggi baris 39px.break-wordsMemastikan teks akan dipatahkan (wrap) jika terlalu panjang untuk satu baris.<span id="formatted-price">280000000</span>Elemen dinamis yang bisa diisi atau diformat menggunakan JavaScript, biasanya untuk menampilkan angka yang sudah diberi pemisah (misal: 280,000,000). JavaScript Baris KodePenjelasanlet priceElement = document.getElementById("formatted-price");Mengambil elemen dengan ID formatted-price dari DOM.let priceValue = parseInt(priceElement.textContent, 10);Mengambil teks dari elemen tersebut (misal: "280000000") dan mengubahnya menjadi angka (280000000).priceElement.textContent = ...Mengganti isi teks elemen dengan hasil format angka.new Intl.NumberFormat("id-ID", {...}).format(priceValue);Menggunakan Internationalization API untuk memformat angka sesuai dengan lokal Indonesia. Slicing 6 Bonus Saldo - Decoration Container Bank Tujuan Ketiga elemen <span> ini tidak berisi konten dan hanya digunakan sebagai elemen latar visual (dekoratif) Code <main class="relative mx-auto w-full max-w-[640px] overflow-hidden min-h-screen py-[151px] px-[37.5px] bg-empty-bg"> <form action="success-checkout.html"> <section id="Card" class="flex flex-col gap-[41px] p-6 rounded-[34px] relative bg-empty-blue-card text-white overflow-hidden"> <div class="flex items-center justify-between relative z-20"> <div> <h2 class="font-light text-sm leading-[21px]">Name</h2> <p><strong class="font-medium text-xl leading-[30px]">Kezia Rifqi</strong></p> </div> <div class="flex items-center gap-[6px] shrink-0"> <img src="assets/images/icons/airplane.svg" alt="" class="size-6 shrink-0" /> <p class="font-medium">Pay</p> </div> </div> <div class="relative z-20"> <h2 class="font-light text-sm leading-[21px]">Balance</h2> <p> <strong class="font-medium text-[26px] leading-[39px] break-words">IDR <span id="formatted-price">280000000</span></strong> </p> </div> <!-- dari sini --> <span class="absolute right-[-38px] top-[-45px] size-[107px] rounded-full bg-empty-shadow-rounded blur-[50px]"></span> <span class="absolute left-[-29px] bottom-[-30px] size-[107px] rounded-full bg-empty-shadow-rounded blur-[50px]"></span> <span class="absolute left-[35px] bottom-[-45px] bg-empty-shadow-card/50 rounded-[25px] right-[35px] h-[45px] blur-2xl"></span> <!-- sampai sini --> </section> </form> </main> Penjelasan ElemenKeterangan1right-[-38px] top-[-45px] → Bulatan blur muncul di pojok kanan atas. Ukuran 107px, full circle, blur 50px.2left-[-29px] bottom-[-30px] → Bulatan blur muncul di pojok kiri bawah. Sama ukuran dan blur seperti elemen pertama.3left-[35px] right-[35px] bottom-[-45px] → Persegi panjang blur horizontal di bagian bawah kontainer, dengan transparansi (/50) dan radius 25px. Slicing 7 Bonus Saldo - Teks Tujuan Bagian <header> ini adalah judul dan penjelasan singkat promosi yang dirancang untuk tampil di tengah layar secara estetis, konsisten dengan desain mobile-first dan tema UI yang modern. Code <main class="relative mx-auto w-full max-w-[640px] overflow-hidden min-h-screen py-[151px] px-[37.5px] bg-empty-bg"> <form action="success-checkout.html"> <section id="Card" class="flex flex-col gap-[41px] p-6 rounded-[34px] relative bg-empty-blue-card text-white overflow-hidden"> <div class="flex items-center justify-between relative z-20"> <div> <h2 class="font-light text-sm leading-[21px]">Name</h2> <p><strong class="font-medium text-xl leading-[30px]">Kezia Rifqi</strong></p> </div> <div class="flex items-center gap-[6px] shrink-0"> <img src="assets/images/icons/airplane.svg" alt="" class="size-6 shrink-0" /> <p class="font-medium">Pay</p> </div> </div> <div class="relative z-20"> <h2 class="font-light text-sm leading-[21px]">Balance</h2> <p> <strong class="font-medium text-[26px] leading-[39px] break-words">IDR <span id="formatted-price">280000000</span></strong> </p> </div> <span class="absolute right-[-38px] top-[-45px] size-[107px] rounded-full bg-empty-shadow-rounded blur-[50px]"></span> <span class="absolute left-[-29px] bottom-[-30px] size-[107px] rounded-full bg-empty-shadow-rounded blur-[50px]"></span> <span class="absolute left-[35px] bottom-[-45px] bg-empty-shadow-card/50 rounded-[25px] right-[35px] h-[45px] blur-2xl"></span> </section> <!-- dari sini --> <header class="mt-[91px] flex flex-col gap-[10px] w-[250px] mx-auto"> <h1 class="text-center font-semibold text-[32px] leading-[48px] text-empty-black">Big Bonus🎉</h1> <p class="text-center font-light leading-[28px] text-empty-grey">We give you early credit so that you can buy a flight ticket</p> </header> <!-- sampai sini --> </form> </main> Penjelasan Elemen/Utility CSSPenjelasan<header>Elemen header berfungsi sebagai bagian pembuka konten (heading + deskripsi).mt-[91px]Memberikan margin atas sejauh 91px untuk memberi ruang dari elemen sebelumnya.flex flex-col gap-[10px]Menyusun konten header secara vertikal dengan jarak 10px antar elemen.w-[250px] mx-autoLebar maksimum 250px dan posisi di tengah secara horizontal.<h1>Judul utama: "Big Bonus🎉", dengan ukuran besar (32px), tinggi baris 48px, font tebal.text-center text-empty-blackTeks di tengah dan warna teks menggunakan variabel tema hitam.<p>Paragraf deskripsi singkat, dengan font ringan dan warna abu-abu dari tema.leading-[28px]Menentukan tinggi baris agar teks paragraf nyaman dibaca. Slicing 8 Bonus Saldo - Button Tujuan Tombol ini berfungsi sebagai pemicu pengiriman form yang akan membawa pengguna ke halaman tujuan success-checkout.html . Code <main class="relative mx-auto w-full max-w-[640px] overflow-hidden min-h-screen py-[151px] px-[37.5px] bg-empty-bg"> <form action="success-checkout.html"> <section id="Card" class="flex flex-col gap-[41px] p-6 rounded-[34px] relative bg-empty-blue-card text-white overflow-hidden"> <div class="flex items-center justify-between relative z-20"> <div> <h2 class="font-light text-sm leading-[21px]">Name</h2> <p><strong class="font-medium text-xl leading-[30px]">Kezia Rifqi</strong></p> </div> <div class="flex items-center gap-[6px] shrink-0"> <img src="assets/images/icons/airplane.svg" alt="" class="size-6 shrink-0" /> <p class="font-medium">Pay</p> </div> </div> <div class="relative z-20"> <h2 class="font-light text-sm leading-[21px]">Balance</h2> <p> <strong class="font-medium text-[26px] leading-[39px] break-words">IDR <span id="formatted-price">280000000</span></strong> </p> </div> <span class="absolute right-[-38px] top-[-45px] size-[107px] rounded-full bg-empty-shadow-rounded blur-[50px]"></span> <span class="absolute left-[-29px] bottom-[-30px] size-[107px] rounded-full bg-empty-shadow-rounded blur-[50px]"></span> <span class="absolute left-[35px] bottom-[-45px] bg-empty-shadow-card/50 rounded-[25px] right-[35px] h-[45px] blur-2xl"></span> </section> <header class="mt-[91px] flex flex-col gap-[10px] w-[250px] mx-auto"> <h1 class="text-center font-semibold text-[32px] leading-[48px] text-empty-black">Big Bonus🎉</h1> <p class="text-center font-light leading-[28px] text-empty-grey">We give you early credit so that you can buy a flight ticket</p> </header> <!-- dari sini --> <button type="submit" class="mt-[50px] font-medium text-lg leading-[27px] text-white bg-empty-blue py-3.5 px-[50px] mx-auto rounded-[17px] flex hover:shadow-lg shadow-empty-blue/40 transition-all duration-300">Start Fly Now</button> <!-- sampai sini --> </form> </main> Penjelasan Elemen/Utility CSSPenjelasantype="submit"Tombol ini akan mengirimkan data dari form jika ditekan.mt-[50px]Memberi jarak 50px dari elemen di atasnya.font-medium text-lg leading-[27px]Teks sedang (medium), ukuran besar (lg = sekitar 18px), dan tinggi baris 27px.text-whiteWarna teks putih agar kontras dengan latar belakang.bg-empty-blueWarna latar belakang tombol sesuai variabel tema biru.py-3.5 px-[50px]Padding vertikal (atas-bawah) 3.5 unit (~14px), horizontal (kanan-kiri) 50px.mx-autoTombol diposisikan secara horizontal di tengah layar.rounded-[17px]Sudut tombol dibuat membulat (border-radius 17px) untuk nuansa modern.flexMengaktifkan flexbox untuk menyusun konten tombol (berguna jika ada ikon + teks).hover:shadow-lgSaat tombol disentuh/mouse hover, muncul efek bayangan besar.shadow-empty-blue/40Bayangan dasar dengan warna biru (dari tema) dan transparansi 40%.transition-all duration-300Efek transisi halus selama 300ms saat hover terjadi. Slicing 9 Success Checkout - Container Tujuan Elemen <main> ini adalah kerangka layout untuk halaman "success-checkout.html", didesain agar tampil rapi, modern, dan optimal di perangkat mobile. Code <main class="relative mx-auto w-full max-w-[640px] overflow-hidden min-h-screen pt-[212px] pb-[151px] px-[37.5px] bg-empty-bg"></main> Penjelasan Elemen/Utility CSSPenjelasanrelativeElemen menjadi konteks posisi untuk elemen absolute di dalamnya.mx-autoMenjadikan elemen ini berada di tengah horizontal.w-fullLebar elemen dibuat penuh dari parent-nya.max-w-[640px]Membatasi lebar maksimum hanya 640px (mobile-first design).overflow-hiddenMenyembunyikan elemen yang meluap dari batas area.min-h-screenTinggi minimum 100% dari tinggi layar perangkat.pt-[212px] pb-[151px]Padding atas 212px dan bawah 151px, memberi ruang konten di dalamnya.px-[37.5px]Padding kiri dan kanan sebesar 37.5px.bg-empty-bgBackground menggunakan warna tema dari variabel CSS. Slicing 10 Success Checkout - Background Image Tujuan Gambar ini adalah ikon sukses berformat .png yang ditampilkan di tengah halaman untuk memperkuat pesan keberhasilan pada halaman seperti success-checkout.html Code <main class="relative mx-auto w-full max-w-[640px] overflow-hidden min-h-screen pt-[212px] pb-[151px] px-[37.5px] bg-empty-bg"> <!-- dari sini --> <img src="assets/images/backgrounds/success-co.png" alt="image" class="h-[150px] shrink-0 mx-auto" /> <!-- sampai sini --> </main> Penjelasan Elemen/Utility CSSPenjelasansrc="assets/images/backgrounds/success-co.png"Menunjukkan sumber gambar berupa file .png, ilustrasi keberhasilan.alt="image"Deskripsi alternatif untuk pembaca layar atau jika gambar gagal dimuat.class="h-[150px]"Mengatur tinggi gambar tetap 150px.shrink-0Mencegah gambar mengecil jika berada dalam kontainer fleksibel (flex).mx-autoMembuat gambar berada di tengah secara horizontal. Slicing 11 Success Checkout - Teks Tujuan Elemen <header> ini adalah bagian dari tampilan halaman sukses yang memberikan ucapan selamat dengan desain ramah pengguna dan mengajak pengguna untuk bersemangat melanjutkan perjalanan mereka. Code <main class="relative mx-auto w-full max-w-[640px] overflow-hidden min-h-screen pt-[212px] pb-[151px] px-[37.5px] bg-empty-bg"> <img src="assets/images/backgrounds/success-co.png" alt="image" class="h-[150px] shrink-0 mx-auto" /> <!-- dari sini --> <header class="mt-[80px] flex flex-col gap-[10px] w-[261px] mx-auto"> <h1 class="text-center font-semibold text-[32px] leading-[48px] text-empty-black">Well Booked 😍</h1> <p class="text-center font-light leading-[28px] text-empty-grey">Are you ready to explore the new world of experiences?</p> </header> <!-- sampai sini --> </main> Penjelasan <header>: Elemen/Utility CSSPenjelasanmt-[80px]Memberi margin atas sebesar 80px dari elemen sebelumnya.flex flex-colMenyusun elemen di dalamnya secara kolom (vertikal).gap-[10px]Memberi jarak antar elemen sebesar 10px.w-[261px]Lebar maksimum header dibatasi 261px.mx-autoMembuat elemen terpusat secara horizontal. <h1>: Elemen/Utility CSSPenjelasantext-centerTeks diratakan ke tengah.font-semiboldMengatur ketebalan teks menjadi semi-bold.text-[32px]Ukuran huruf 32px.leading-[48px]Jarak antar baris 48px.text-empty-blackWarna teks menggunakan variabel tema --color-empty-black. <p>: Elemen/Utility CSSPenjelasantext-centerTeks diratakan ke tengah.font-lightMengatur ketebalan teks menjadi tipis.leading-[28px]Jarak antar baris 28px.text-empty-greyWarna teks menggunakan variabel tema --color-empty-grey. Slicing 12 Success Checkout - Button Tujuan Elemen ini berfungsi sebagai tombol ajakan yang dirancang responsif dan menarik untuk pengguna mengakses data pemesanan mereka dengan nyaman. Code <main class="relative mx-auto w-full max-w-[640px] overflow-hidden min-h-screen pt-[212px] pb-[151px] px-[37.5px] bg-empty-bg"> <img src="assets/images/backgrounds/success-co.png" alt="image" class="h-[150px] shrink-0 mx-auto" /> <header class="mt-[80px] flex flex-col gap-[10px] w-[261px] mx-auto"> <h1 class="text-center font-semibold text-[32px] leading-[48px] text-empty-black">Well Booked 😍</h1> <p class="text-center font-light leading-[28px] text-empty-grey">Are you ready to explore the new world of experiences?</p> </header> <!-- dari sini --> <a href="#" class="mt-[50px] font-medium w-fit text-lg leading-[27px] text-white text-center bg-empty-blue py-3.5 px-[50px] mx-auto rounded-[17px] flex hover:shadow-lg shadow-empty-blue/40 transition-all duration-300">My Bookings</a> <!-- sampai sini --> </main> Penjelasan Elemen/Utility CSSPenjelasanhref="#"Tautan dummy, biasanya nanti diisi ke halaman seperti bookings.html.mt-[50px]Memberi jarak ke atas sebesar 50px.font-mediumMengatur ketebalan teks menjadi medium.w-fitLebar tombol menyesuaikan isi teks.text-lgUkuran teks besar (sekitar 18px).leading-[27px]Jarak antar baris teks 27px.text-whiteWarna teks putih.text-centerMeratakan teks ke tengah.bg-empty-blueWarna latar menggunakan variabel tema --color-empty-blue.py-3.5 / px-[50px]Padding vertikal dan horizontal untuk ukuran tombol yang nyaman.mx-autoMenempatkan tombol di tengah secara horizontal.rounded-[17px]Membuat sudut tombol melengkung 17px.flexMenjadikan elemen sebagai flex container (berguna jika diisi ikon juga).hover:shadow-lgMenambahkan bayangan besar saat kursor diarahkan.shadow-empty-blue/40Bayangan dengan warna biru transparan (40%).transition-all duration-300Efek transisi halus selama 300ms saat hover. Penutup Semoga hasil slicing ini dapat memberikan manfaat dan wawasan baru. Memahami struktur serta alur slicing dengan baik akan sangat berguna ke depannya baik untuk pengembangan proyek, sebagai referensi desain, aset komersial, maupun untuk diintegrasikan dengan berbagai bahasa pemrograman secara lebih efisien. Jangan lupa kunjungi website resmi shaynakit.com untuk mendapatkan berbagai desain dan file HTML gratis yang dapat langsung digunakan dalam proyek Anda. Terima kasih!

Kelas Panduan Lengkap : Mengubah Desain Figma Menjadi HTML dengan Tailwind CSS dan JavaScript di BuildWithAngga

Panduan Lengkap : Mengubah Desain Figma Menjadi HTML dengan Tailwind CSS dan JavaScript

Daftar Isi Persiapan ProyekStruktur FolderSetupMembuat Bagian Header #1Membuat Section HeroMembuat Section Logo KlienMembuat Section KeunggulanMembuat Section TestimonialFinalisasi dan DeployPenutup Persiapan Proyek Sebelum memulai, pastikan kamu memiliki : Editor kode (VS Code direkomendasikan)Node.js terinstalBrowser modern (Chrome/Firefox)Link Google Drive untuk mengakses desain dan asset https://drive.google.com/drive/folders/1VzNs5JXJC8Y9To0gtMrv80Dda3nNbl9c?usp=sharing Buat Folder “BankMo”Buka Folder di Visual Studio CodeBuka Terminal di VscodeJalankan npm install tailwindcss @tailwindcss/clibuat folder srcBuat file input.css di dalam src dan tambahkan @import "tailwindcss";Jalankan npx @tailwindcss/cli -i ./src/input.css -o ./src/output.css --watch untuk membangun css Struktur Folder bankmo-project/ ├── node_modules/ ├── src/ │ ├── assets/ │ │ ├── images/ │ │ │ ├── icons/ │ │ │ ├── logos/ │ │ │ └── photos/ │ ├── fonts.css │ ├── styles.css │ ├── comment.js │ ├── navbar.js │ ├── index.html │ └── output.css | └── input.css ├── .gitignore ├── package-lock.json ├── package.json Setup Hal yang pertama kali dilakukan adalah membuka desain figma. BankMo - Landing Page Analisa font apa yang digunakan pada desain di atas, ternyata menggunakan Poppins dan Montserrat untuk font logo. Setelah mengetahui hal di atas, maka kita perlu membuka file src/fonts.css untuk menerapkan font yang akan dipakai. @import url('<https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap>'); .text-logo{ font-family: 'Montserrat'; } body{ font-family: 'Poppins'; } Ketika sudah selesai, maka langkah selanjutnya adalah : Membuat file index.html di dalam src dengan struktur awal sebagai berikut : src/index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="output.css"> <link rel="stylesheet" href="fonts.css"> <link rel="stylesheet" href="styles.css"> <title>BankMo | Home</title> </head> <body> <header> <-- Konten Navbar --> </header> <main> <-- Konten Utama --> </main> <script src="navbar.js"></script> <script src="comment.js"></script> </body> </html> Membuat Bagian Header #1 Sebelum mulai pada pembuatan bagian header, kita perlu set breakpoint untuk membuat batas tiap layar, berikut adalah daftar breakpoint yang saya gunakan : sm : min-width (≥640px)md : min-width (≥768px)lg : min-width (≥1024px)xl : min-width (≥1280px)2xl : min-width (≥1512px) Daftar breakpoint di atas sebagian besar adalah bawaan tailwind, tetapi pada 2xl menjadi pengecualian karena menyesuaikan screen dari desain yang akan diubah adalah 1512px maka dari itu kita perlu memberikan kustom tambahan pada TailwindCSS. berikut adalah langkah - langkahnya : Buka file src/input.cssTambahkan @theme{ --breakpoint-2xl: 94.5rem; } Jika sudah melakukan langkah di atas maka selanjutnya adalah membuat konten header yang berisi navbar pada layar desktop ≥1512px Ketik Kode ini di dalam Tag <header> <nav class="px-[100px] pt-[50px] flex items-center justify-between"> <div class="flex items-center gap-x-[70px]"> <div> <a href=""> <h6 class="text-[32px] font-bold text-[#13214A] text-logo"> Bank<span class="text-[#0E45FF]">Mo</span> </h6> </a> </div> <ul class="flex items-center gap-x-[40px] text-[16px] text-[#13214A]"> <li class="relative group hover:font-semibold transition-all duration-300"> <a href="" class="block">Features</a> <div class="absolute bottom-0 left-0 w-full h-[1px] bg-[#0E45FF] rounded-full opacity-0 group-hover:opacity-100 transition-all duration-300"></div> </li> <li class="relative group hover:font-semibold transition-all duration-300"> <a href="" class="block">Pricing</a> <div class="absolute bottom-0 left-0 w-full h-[1px] bg-[#0E45FF] rounded-full opacity-0 group-hover:opacity-100 transition-all duration-300"></div> </li> <li class="relative group hover:font-semibold transition-all duration-300"> <a href="" class="block">Showcase</a> <div class="absolute bottom-0 left-0 w-full h-[1px] bg-[#0E45FF] rounded-full opacity-0 group-hover:opacity-100 transition-all duration-300"></div> </li> <li class="relative group hover:font-semibold transition-all duration-300"> <a href="" class="block">Teams</a> <div class="absolute bottom-0 left-0 w-full h-[1px] bg-[#0E45FF] rounded-full opacity-0 group-hover:opacity-100 transition-all duration-300"></div> </li> </ul> </div> <div class="flex items-center gap-x-[16px]"> <div> <a href=""> <div class="border border-[#13214A] text-[#12204A] w-[159px] pt-[15px] pb-[16px] flex items-center justify-center rounded-[50px] hover:bg-[#13214A] hover:text-white transition-all duration-300 text-[16px]"> My Account </div> </a> </div> <div> <a href=""> <div class="bg-[#0E45FF] text-white font-semibold w-[159px] pt-[15px] pb-[16px] flex items-center justify-center rounded-[50px] hover:shadow-sm hover:shadow-[#0E45FF] transition-all duration-300 text-[16px]"> Sign Up </div> </a> </div> </div> </nav> Lalu akan menghasilkan seperti ini : Ketika sudah membuat versi desktop, maka selanjutnya adalah membuat versi mobile dan tablet dengan kode sebagai berikut : <nav class="px-[30px] md:px-[60px] lg:px-[100px] pt-[35px] md:pt-[50px] flex items-center justify-between"> <div class="flex items-center gap-x-[70px]"> <div> <a href=""> <h6 class="text-[32px] font-bold text-[#13214A] text-logo">Bank<span class="text-[#0E45FF]">Mo</span></h6> </a> </div> <ul class="hidden 2xl:flex items-center gap-x-[40px] text-[16px] text-[#13214A]"> <li class="relative group hover:font-semibold transition-all duration-300"> <a href="" class="block">Features</a> <div class="absolute bottom-0 left-0 w-full h-[1px] bg-[#0E45FF] rounded-full opacity-0 group-hover:opacity-100 transition-all duration-300"></div> </li> <li class="relative group hover:font-semibold transition-all duration-300"> <a href="" class="block">Pricing</a> <div class="absolute bottom-0 left-0 w-full h-[1px] bg-[#0E45FF] rounded-full opacity-0 group-hover:opacity-100 transition-all duration-300"></div> </li> <li class="relative group hover:font-semibold transition-all duration-300"> <a href="" class="block">Showcase</a> <div class="absolute bottom-0 left-0 w-full h-[1px] bg-[#0E45FF] rounded-full opacity-0 group-hover:opacity-100 transition-all duration-300"></div> </li> <li class="relative group hover:font-semibold transition-all duration-300"> <a href="" class="block">Teams</a> <div class="absolute bottom-0 left-0 w-full h-[1px] bg-[#0E45FF] rounded-full opacity-0 group-hover:opacity-100 transition-all duration-300"></div> </li> </ul> </div> <div class="hidden 2xl:flex items-center gap-x-[16px]"> <div> <a href=""> <div class="border border-[#13214A] text-[#12204A] w-[159px] pt-[15px] pb-[16px] flex items-center justify-center rounded-[50px] hover:bg-[#13214A] hover:text-white transition-all duration-300 text-[16px]">My Account</div> </a> </div> <div> <a href=""> <div class="bg-[#0E45FF] text-white font-semibold w-[159px] pt-[15px] pb-[16px] flex items-center justify-center rounded-[50px] hover:shadow-sm hover:shadow-[#0E45FF] transition-all duration-300 text-[16px]">Sign Up</div> </a> </div> </div> <div class="block 2xl:hidden"> <button onclick="toggleSidebar()"> <img src="assets/images/icons/hamburger.svg" alt="Menu" class="w-[28px] h-[28px]"> </button> </div> </nav> <div id="sidebarOverlay" class="fixed inset-0 bg-black bg-opacity-50 z-40 hidden 2xl:hidden" onclick="toggleSidebar()"></div> <div id="mobileSidebar" class="fixed top-0 right-0 w-[250px] h-full bg-white z-50 transform translate-x-full transition-transform duration-300 2xl:hidden shadow-lg overflow-y-auto"> <div class="p-6 flex flex-col gap-y-6 text-[#13214A] text-[16px]"> <button onclick="toggleSidebar()" class="self-end mt-6 me-2 sm:me-8 sm:mt-9 lg:me-2 lg:mt-6"> <img src="assets/images/icons/close.svg" alt="Close" class="w-[24px] h-[24px]"> </button> <a href="" class="hover:font-semibold transition-all duration-300">Features</a> <a href="" class="hover:font-semibold transition-all duration-300">Pricing</a> <a href="" class="hover:font-semibold transition-all duration-300">Showcase</a> <a href="" class="hover:font-semibold transition-all duration-300">Teams</a> <hr> <a href="" class="border border-[#13214A] text-center py-2 rounded-full hover:bg-[#13214A] hover:text-white transition-all duration-300">My Account</a> <a href="" class="bg-[#0E45FF] text-white text-center py-2 rounded-full font-semibold hover:shadow hover:shadow-[#0E45FF] transition-all duration-300">Sign Up</a> </div> </div> Struktur Navigasi Utama (<nav>) Wrapper <nav>Menggunakan padding horizontal (px) dan top padding (pt) yang responsif: 30px untuk default, 60px untuk md, dan 100px untuk lg.Menggunakan flex, items-center, dan justify-between untuk menyusun logo di kiri dan menu di kanan.Bagian Kiri: Logo & Menu Desktopdiv.flex.items-center.gap-x-[70px]:Logo "BankMo"Menggunakan text-[32px], font-bold, dan pewarnaan berbeda untuk kata "Bank" dan "Mo".Menu Navigasi (Hanya muncul di layar 2xl ke atas)Menggunakan ul.hidden.2xl:flex agar hanya muncul di layar besar.Tiap item li memiliki animasi hover berupa garis bawah tipis (h-[1px]) yang muncul dengan transisi lembut.Bagian Kanan: Tombol Akun & Sign Up (Desktop Only)Hanya muncul di resolusi 2xl ke atas.Tombol:My Account: Bordered, warna teks default, berubah jadi putih dengan latar navy saat hover.Sign Up: Background biru #0E45FF, font tebal, animasi shadow saat hover.Menu Hamburger (Mobile & Tablet)Muncul di layar < 2xl (block 2xl:hidden).Tombol memicu fungsi toggleSidebar() yang akan membuka/menutup sidebar. Overlay Sidebar Mobile #sidebarOverlayElemen semi-transparan hitam (bg-opacity-50) yang muncul di belakang sidebar.Menggunakan z-40 agar muncul di atas konten, tapi di bawah sidebar (z-50).Disembunyikan default (hidden) dan hanya muncul saat sidebar aktif.Klik overlay juga memanggil toggleSidebar() untuk menutup menu. Sidebar Mobile (#mobileSidebar) Wrapper Sidebarfixed top-0 right-0 agar muncul dari kanan atas layar.Lebar 250px, tinggi penuh (h-full), warna latar putih.Transisi translate-x-full secara default (tersembunyi), lalu diubah oleh toggleSidebar() agar muncul (translate-x-0).Scroll aktif jika isi overflow (overflow-y-auto).Isi SidebarPadding p-6, dengan spacing antar elemen gap-y-6.Tombol Close:Ikon "X" (gambar close.svg), berada di kanan atas sidebar.Link Navigasi:Sama seperti desktop: Features, Pricing, Showcase, Teams.Aksi Pengguna:My Account: Tombol border dengan efek hover.Sign Up: Tombol biru solid dengan shadow saat hover. Ketika sudah selesai membuat versi mobile dan desktop maka tampilannya akan menjadi seperti ini : BankMo - Nav Top Buka file src/navbar.js dan implementasikan fungsi toggle untuk menampilkan/menyembunyikan aside saat tombol hamburger diklik. function toggleSidebar() { const sidebar = document.getElementById('mobileSidebar'); const overlay = document.getElementById('sidebarOverlay'); const body = document.body; const isOpen = sidebar.classList.contains('translate-x-0'); if (isOpen) { sidebar.classList.add('translate-x-full'); sidebar.classList.remove('translate-x-0'); overlay.classList.add('hidden'); body.classList.remove('overflow-hidden'); } else { sidebar.classList.remove('translate-x-full'); sidebar.classList.add('translate-x-0'); overlay.classList.remove('hidden'); body.classList.add('overflow-hidden'); } } Menu navigasi dan tombol CTA akan tersembunyi, kemudian akan muncul panel samping (aside) ketika tombol hamburger di sebelah diklik. Berikut adalah contohnya : BankMo - Landing Page Membuat Section Hero Mari kita bahas pembuatan section hero mulai dari tampilan desktop hingga mobile. 1. Tampilan Desktop (>1512px) Untuk tampilan desktop, kita menggunakan layout side-by-side dengan konten di kiri dan gambar di kanan : <section class="mt-[70px]"> <div class="w-full max-w-[1512px] mx-auto px-[130px] flex items-center justify-between"> <!-- Konten kiri --> <div class="flex flex-col items-start text-start"> <h1 class="text-[46px] font-bold text-[#13214A] max-w-[462px] leading-[69px]"> Protect Your Money Securely With Us. </h1> <p class="text-[16px] text-[#78839E] leading-[32px] max-w-[393px] mt-[20px]"> Keep your company cashflow better and grow the business would be better integrated systems. </p> <div class="mt-[40px]"> <a href="#"> <div class="bg-[#0E45FF] text-white font-semibold w-[250px] py-[20px] flex items-center justify-center rounded-[50px] hover:shadow-sm hover:shadow-[#0E45FF] transition-all duration-300 text-[20px]"> Protect My Money </div> </a> </div> </div> <!-- Gambar kanan --> <div class="relative shrink-0"> <img src="assets/images/photos/hero-image.png" alt="" class="w-[680px] h-[520px] object-cover rounded-[40px] shrink-0"> <div class="absolute bg-white flex items-center justify-center px-[26px] py-[13px] rounded-[54px] bottom-[-25px] right-[118px] shadow__element"> <div class="flex items-center gap-x-[14px]"> <img src="assets/images/icons/checklist.svg" alt="" class="w-[24px] h-[24px] shrink-0"> <p class="text-[16px] font-semibold text-[#13214A]"> The most trusted system in the global world </p> </div> </div> </div> </div> </section> Section utama:mt-[70px]: Memberikan margin atas 70px dari elemen sebelumnya.Container utama:max-w-[1512px] mx-auto: Lebar maksimum 1512px dan posisi tengah secara horizontal.px-[130px]: Padding kiri dan kanan 130px.flex items-center justify-between: Mengatur isi menjadi 2 kolom sejajar (konten kiri dan gambar kanan), rata tengah secara vertikal dan tersebar rata secara horizontal. Konten Kiri flex flex-col items-start text-start:Mengatur isi dalam kolom (vertikal) dan teks rata kiri.Elemen Judul (<h1>):Ukuran teks 46px, font-bold, warna biru tua (#13214A).max-w-[462px]: Batas lebar maksimum agar teks tidak terlalu panjang.leading-[69px]: Jarak antar baris.Paragraf deskripsi:Ukuran teks 16px, warna abu #78839E, leading-[32px] untuk kenyamanan baca.max-w-[393px] dan mt-[20px]: Jarak atas dari judul.Tombol “Protect My Money”:mt-[40px]: Jarak atas dari paragraf.Tombol berwarna biru #0E45FF, teks putih, font-semibold.Lebar 250px, padding vertikal 20px, rounded-full.Ada efek hover shadow biru. Gambar Kanan Container gambar:relative shrink-0: Untuk memungkinkan penempatan elemen secara absolut di dalamnya.Gambar utama:Ukuran tetap: lebar 680px, tinggi 520px, sudut membulat 40px.object-cover: Gambar tetap proporsional tanpa distorsi.Elemen info tambahan (keterangan di bawah gambar):absolute: Diposisikan di pojok kanan bawah gambar.bottom-[-25px] right-[118px]: Posisinya diatur agar melayang sebagian ke luar gambar.bg-white, padding px-[26px] py-[13px], rounded-[54px], dan shadow__element: Membentuk kotak info dengan bayangan.Isi elemen info:flex items-center gap-x-[14px]: Ikon dan teks sejajar dengan jarak antar elemen.Teks: ukuran 16px, font-semibold, warna biru tua. 2. Tampilan Mobile & Tablet (320px - 1511px) <section class="mt-[70px]"> <div class="w-full max-w-[1512px] mx-auto px-[30px] lg:px-[130px] flex items-center justify-start sm:justify-center 2xl:justify-between"> <div class="flex flex-col sm:items-center sm:text-center 2xl:items-start 2xl:text-start"> <h1 class="text-[30px] sm:text-[46px] font-bold text-[#13214A] max-w-[462px] md:leading-[69px]">Protect Your Money Securely With Us.</h1> <p class="text-[14px] md:text-[16px] text-[#78839E] md:leading-[32px] max-w-[393px] mt-[20px]">Keep your company cashflow better and grow the business would be better integrated systems.</p> <div class="mt-[20px] md:mt-[30px] 2xl:mt-[40px]"> <a href=""> <div class="bg-[#0E45FF] text-white font-semibold w-[180px] md:w-[200px] 2xl:w-[250px] py-[14px] md:py-[16px] 2xl:py-[20px] flex items-center justify-center rounded-[50px] hover:shadow-sm hover:shadow-[#0E45FF] transition-all duration-300 text-[16px] md:text-[18px] 2xl:text-[20px]">Protect My Money</div> </a> </div> </div> <div class="relative shrink-0 hidden 2xl:block"> <img src="assets/images/photos/hero-image.png" alt="" class="w-[680px] h-[520px] object-cover rounded-[40px] shrink-0"> <div class="absolute bg-white flex items-center justify-center px-[26px] py-[13px] rounded-[54px] bottom-[-25px] right-[118px] shadow__element"> <div class="flex items-center gap-x-[14px]"> <img src="assets/images/icons/checklist.svg" alt="" class="w-[24px] h-[24px] shrink-0"> <p class="text-[16px] font-semibold text-[#13214A]">The most trusted system in the global world</p> </div> </div> </div> </div> </section> Struktur Section Hero (Responsif) <section class="mt-[70px]">Memberi margin atas 70px agar tidak terlalu menempel ke elemen sebelumnya. Container Utama <div class="w-full max-w-[1512px] mx-auto px-[30px] lg:px-[130px] flex items-center justify-start sm:justify-center 2xl:justify-between">Lebar penuh tapi dibatasi max-w-[1512px].Padding horizontal kecil di mobile (30px) dan lebih lebar di desktop (130px).Flex container untuk 2 elemen horizontal.Posisi isi:justify-start di mobile,justify-center di small screen (sm),justify-between di ultra-wide (2xl) agar teks kiri dan gambar kanan tersebar rata. Konten Kiri <div class="flex flex-col sm:items-center sm:text-center 2xl:items-start 2xl:text-start">Stack vertikal.Teks rata tengah di sm, dan rata kiri di 2xl.<h1>:Teks judul responsif:text-[30px] di mobile,text-[46px] di sm ke atas.Maksimal lebar 462px, font-bold, warna biru tua.Line height 69px di md.<p>:Ukuran teks 14px di mobile dan 16px di md.Warna abu muda, jarak antar baris 32px di md.Maksimal lebar 393px, mt-[20px].Tombol:Margin atas bertingkat:20px di mobile,30px di md,40px di 2xl.Lebar dan padding responsif:180px dan 14px di mobile,200px dan 16px di md,250px dan 20px di 2xl.Warna biru, teks putih, font-semibold.Hover ada efek bayangan ringan (shadow-sm). Gambar Kanan (Hanya di Layar Besar) <div class="relative shrink-0 hidden 2xl:block">Gambar hanya tampil di layar 2xl (tidak muncul di mobile).relative untuk posisi elemen anak yang absolut.<img>:Gambar dengan ukuran tetap 680x520px, object-cover agar tidak terdistorsi.Sudut membulat 40px.Elemen info tambahan (tooltip di bawah gambar):Posisi absolut bottom-[-25px] right-[118px].Warna putih, padding dalam px-[26px] py-[13px], membulat penuh (rounded-[54px]).Bayangan (shadow__element) agar tampak seperti melayang.Isi tooltip:Ikon checklist dan teks berdampingan, gap-x-[14px].Teks ukuran 16px, font-semibold, warna biru tua. Pada kode di atas, kita menambahkan class breakpoint seperti sm md lg dan 2xl untuk mendapatkan tampilan yang responsive di semua perangkat. Hasil akhir akan seperti ini: Versi Mobile : BankMo - Header Mobile Versi Tablet : BankMo - Header Tablet Versi Desktop : BankMo - Header Dekstop Membuat Section Logo Klien Selanjutnya, kita akan membuat section logo klien. Bagian ini biasanya dipakai untuk menunjukkan logo-logo brand atau perusahaan yang pernah kerja sama dengan kita. 1. Tampilan Desktop (>1512px) <section class="w-full flex items-center justify-center mt-[100px]"> <div class="flex items-center gap-x-[92.8px]"> <img src="assets/images/logos/logo-1.svg" alt="" class="w-[212.17px] h-[61px] shrink-0"> <img src="assets/images/logos/logo-2.svg" alt="" class="w-[177.7px] h-[45.09px] shrink-0"> <img src="assets/images/logos/logo-3.svg" alt="" class="w-[164.43px] h-[42.43px] shrink-0"> <img src="assets/images/logos/logo-4.svg" alt="" class="w-[201.57px] h-[25.2px] shrink-0"> </div> </section> Menggunakan flex horizontal agar logo sejajar.gap-x-[92.8px] memberi jarak antar logo.Ukuran logo disesuaikan agar terlihat proporsional. 2. Tampilan Mobile & Tablet (320px - 1511px) <section class="w-full flex flex-col items-center justify-center mt-[100px] px-[30px] sm:px-[40px] md:px-[60px] 2xl:px-0"> <div class="w-full grid grid-cols-1 sm:grid-cols-2 md:flex md:flex-row items-center justify-center gap-[40px] md:gap-x-[60px] lg:gap-x-[92.8px]"> <div class="flex justify-center"> <img src="assets/images/logos/logo-1.svg" alt="" class="w-[160px] h-[46px] sm:w-[180px] sm:h-[52px] md:w-[160px] md:h-[46px] lg:w-[212.17px] lg:h-[61px]"> </div> <div class="flex justify-center"> <img src="assets/images/logos/logo-2.svg" alt="" class="w-[140px] h-[35px] sm:w-[160px] sm:h-[40px] md:w-[130px] md:h-[33px] lg:w-[177.7px] lg:h-[45.09px]"> </div> <div class="flex justify-center"> <img src="assets/images/logos/logo-3.svg" alt="" class="w-[130px] h-[33px] sm:w-[150px] sm:h-[38px] md:w-[120px] md:h-[31px] lg:w-[164.43px] lg:h-[42.43px]"> </div> <div class="flex justify-center"> <img src="assets/images/logos/logo-4.svg" alt="" class="w-[150px] h-[19px] sm:w-[170px] sm:h-[22px] md:w-[150px] md:h-[19px] lg:w-[201.57px] lg:h-[25.2px]"> </div> </div> </section> Gunakan grid atau flex tergantung lebar layar.Logo dibungkus dalam <div class="flex justify-center"> agar selalu berada di tengah.Ukuran logo disesuaikan per breakpoint (sm, md, lg) agar tampil konsisten dan tidak terlalu besar/kecil. BankMo - Logos BankMo - Logos Membuat Section Keunggulan Setelah membuat Section Logo Klien, selanjutnya kita akan membuat Section Keunggulan yang menampilkan berbagai keunggulan utama dari website kita. Bagian ini bertujuan untuk meyakinkan pengunjung dengan menampilkan fitur-fitur unggulan yang dimiliki. Section ini dibagi menjadi 2 bagian utama : Judul dan deskripsi singkat di tengah halaman.Tiga kotak keunggulan berisi ikon, judul fitur, dan penjelasan singkat. 1. Tampilan Desktop (>1512px) <section class="mt-[100px]"> <div class="w-full bg-[#0B142F] flex items-center justify-center px-[318px] py-[100px]"> <div class="flex flex-col items-center text-center"> <h2 class="text-[32px] font-semibold text-white">Why Choose Us</h2> <p class="text-[16px] leading-[32px] text-[#77809D] px-[254px] mt-[20px]">Reasonable option for growing your company and working more automatically with us</p> <div class="mt-[70px] grid grid-cols-3 gap-[90px]"> <div class="flex flex-col items-start text-start"> <div class="bg-[#0E45FF] flex items-center justify-center w-[60px] h-[60px] rounded-full"> <img src="assets/images/icons/globe.svg" alt="" class="w-[24px] h-[24px] shrink-0"> </div> <div class="mt-[30px]"> <h6 class="text-[20px] font-medium text-white">Biggest Database</h6> <p class="text-[16px] leading-[24px] text-[#77809D] mt-[10px]">Access customer data to make business choice</p> </div> </div> <div class="flex flex-col items-start text-start"> <div class="bg-[#0E45FF] flex items-center justify-center w-[60px] h-[60px] rounded-full"> <img src="assets/images/icons/download.svg" alt="" class="w-[24px] h-[24px] shrink-0"> </div> <div class="mt-[30px]"> <h6 class="text-[20px] font-medium text-white">Offline Docs</h6> <p class="text-[16px] leading-[24px] text-[#77809D] mt-[10px]">No need Internet connection to get the latest report</p> </div> </div> <div class="flex flex-col items-start text-start"> <div class="bg-[#0E45FF] flex items-center justify-center w-[60px] h-[60px] rounded-full"> <img src="assets/images/icons/database.svg" alt="" class="w-[24px] h-[24px] shrink-0"> </div> <div class="mt-[30px]"> <h6 class="text-[20px] font-medium text-white">Most Secure</h6> <p class="text-[16px] leading-[24px] text-[#77809D] mt-[10px]">We ensure that every single database would be safe</p> </div> </div> </div> </div> </div> </section> Warna latar belakang gelap (bg-[#0B142F]) membuat konten terlihat menonjol.Menggunakan grid-cols-3 untuk menampilkan 3 keunggulan secara sejajar.Icon dibungkus bulat dengan bg-[#0E45FF] dan ukuran tetap (60px x 60px). BankMo - Why Choose Us Dekstop 2. Tampilan Mobile & Tablet (320px - 1511px) <section class="mt-[100px]"> <div class="w-full bg-[#0B142F] flex items-center justify-center px-[30px] sm:px-[60px] md:px-[100px] lg:px-[140px] 2xl:px-[318px] py-[60px] md:py-[100px]"> <div class="flex flex-col items-center text-center"> <h2 class="text-[24px] md:text-[32px] font-semibold text-white">Why Choose Us</h2> <p class="text-[14px] md:text-[16px] md:leading-[32px] text-[#77809D] sm:px-[100px] md:px-[160px] 2xl:px-[254px] mt-[10px] md:mt-[20px]">Reasonable option for growing your company and working more automatically with us</p> <div class="mt-[40px] md:mt-[70px] grid md:grid-cols-3 gap-[30px] md:gap-[90px]"> <div class="flex flex-col items-center md:items-start md:text-start"> <div class="bg-[#0E45FF] flex items-center justify-center w-[60px] h-[60px] rounded-full"> <img src="assets/images/icons/globe.svg" alt="" class="w-[24px] h-[24px] shrink-0"> </div> <div class="mt-[20px] md:mt-[30px]"> <h6 class="text-[18px] font-medium text-white">Biggest Database</h6> <p class="text-[14px] md:text-[16px] md:leading-[24px] text-[#77809D] mt-[10px]">Access customer data to make business choice</p> </div> </div> <div class="flex flex-col items-center md:items-start md:text-start"> <div class="bg-[#0E45FF] flex items-center justify-center w-[60px] h-[60px] rounded-full"> <img src="assets/images/icons/download.svg" alt="" class="w-[24px] h-[24px] shrink-0"> </div> <div class="mt-[20px] md:mt-[30px]"> <h6 class="text-[18px] font-medium text-white">Offline Docs</h6> <p class="text-[14px] md:text-[16px] md:leading-[24px] text-[#77809D] mt-[10px]">No need Internet connection to get the latest report</p> </div> </div> <div class="flex flex-col items-center md:items-start md:text-start"> <div class="bg-[#0E45FF] flex items-center justify-center w-[60px] h-[60px] rounded-full"> <img src="assets/images/icons/database.svg" alt="" class="w-[24px] h-[24px] shrink-0"> </div> <div class="mt-[20px] md:mt-[30px]"> <h6 class="text-[18px] font-medium text-white">Most Secure</h6> <p class="text-[14px] md:text-[16px] md:leading-[24px] text-[#77809D] mt-[10px]">We ensure that every single database would be safe</p> </div> </div> </div> </div> </div> </section> Gunakan padding dan font size yang berbeda-beda sesuai ukuran layar.Grid keunggulan otomatis menjadi satu kolom di mobile, tiga kolom di desktop.Posisi teks dan icon berubah dari center ke kiri saat masuk ke sm (medium screen ke atas). BankMo - Why Choose Us Tablet BankMo - Why Choose Us Mobile Membuat Section Testimonial Section Testimonial digunakan untuk menampilkan komentar atau ulasan dari pengguna yang telah mencoba layanan atau produk kita. Tujuannya adalah meningkatkan kepercayaan dan memberikan bukti sosial bahwa website atau bisnis kita memang terpercaya dan berkualitas. Section testimonial dibagi menjadi tiga bagian utama: Tombol NavigasiTombol kiri (sebelumnya) dan kanan (selanjutnya) untuk berpindah antar komentar.Diberi ikon panah dan dibungkus dalam elemen <button>.Kontainer TestimonialBagian tengah berisi komentar pengguna yang sedang ditampilkan.Komentar diletakkan dalam <div> dengan ID testimonialContainer.Tambahkan animasi transition agar perubahan komentar terasa halus.Dekorasi KutipanGambar ikon kutipan (quotation.svg) diletakkan di belakang komentar sebagai hiasan.Menggunakan absolute positioning agar tidak mengganggu teks. 1. Tampilan Desktop (>1512px) <section class="my-[100px]"> <div class="max-w-[1512px] mx-auto flex justify-between px-[130px]"> <button type="button" id="prevButton" class="mt-[133px] border border-[#78839E] rounded-full flex items-center justify-center w-[50px] h-[50px] flex-none cursor-pointer"> <img src="assets/images/icons/arrow.svg" alt="Previous" class="w-[24px] h-[24px] shrink-0"> </button> <div class="flex flex-col items-center overflow-hidden relative w-full"> <div id="testimonialContainer" class="flex items-center justify-center transition-all duration-300 ease-in-out min-h-[374px] z-50 text-[#13214A]"> <!-- Komentar Disini --> </div> <div class="absolute left-[180px] top-[75px] z-0"> <img src="assets/images/icons/quotation.svg" alt="" class="w-[112px] h-auto"> </div> </div> <button type="button" id="nextButton" class="mt-[133px] border border-[#78839E] rounded-full flex items-center justify-center w-[50px] h-[50px] flex-none cursor-pointer"> <img src="assets/images/icons/arrow.svg" alt="Next" class="w-[24px] h-[24px] rotate-180 shrink-0"> </button> </div> </section> Gunakan flex justify-between untuk menempatkan tombol navigasi di kiri dan kanan.Komentar berada di tengah dalam elemen #testimonialContainer.Gambar kutipan diletakkan di background menggunakan posisi absolute agar tampil estetik. BankMo - Testimonial Dekstop 2. Tampilan Mobile & Tablet (320px - 1511px) <section class="my-[30px] md:my-[100px] px-[30px]"> <div class="max-w-[1512px] mx-auto flex justify-between sm:px-[60px] xl:px-[120px] 2xl:px-[130px]"> <button type="button" id="prevButton" class="mt-[133px] border border-[#78839E] rounded-full flex items-center justify-center w-[40px] h-[40px] md:w-[50px] md:h-[50px] flex-none cursor-pointer"> <img src="assets/images/icons/arrow.svg" alt="Previous" class="w-[20px] h-[20px] md:w-[24px] md:h-[24px] shrink-0"> </button> <div class="flex flex-col items-center overflow-hidden relative w-full"> <div id="testimonialContainer" class="flex items-center justify-center transition-all duration-300 ease-in-out min-h-[374px] z-50 text-[#13214A]"> <!-- Komentar Disini --> </div> <div class="absolute left-[40px] top-[200px] md:top-[140px] 2xl:left-[180px] 2xl:top-[75px] z-0"> <img src="assets/images/icons/quotation.svg" alt="" class="w-[40px] sm:w-[60px] md:w-[80px] 2xl:w-[112px] h-auto"> </div> </div> <button type="button" id="nextButton" class="mt-[133px] border border-[#78839E] rounded-full flex items-center justify-center w-[40px] h-[40px] md:w-[50px] md:h-[50px] flex-none cursor-pointer"> <img src="assets/images/icons/arrow.svg" alt="Next" class="w-[20px] h-[20px] md:w-[24px] md:h-[24px] rotate-180 shrink-0"> </button> </div> </section> Tombol panah dan ikon kutipan menyesuaikan ukuran layar menggunakan breakpoint (sm, md, 2xl).Margin dan padding diatur agar tidak terlalu mepet di layar kecil.#testimonialContainer tetap berada di tengah dan punya animasi transition untuk navigasi antar komentar. BankMo - Testimonial Mobile BankMo - Testimonial Tablet Mengatur Animasi slide komentar Untuk membuat perpindahan antar testimonial lebih halus dan menarik secara visual, kita bisa menambahkan animasi sliding ketika tombol navigasi diklik. Animasi ini memberikan efek testimonial masuk dari kiri atau kanan. Buka file src/comment.js . Ketik kode berikut : document.addEventListener('DOMContentLoaded', () => { const testimonialContainer = document.getElementById('testimonialContainer'); const prevButton = document.getElementById('prevButton'); const nextButton = document.getElementById('nextButton'); let currentIndex = 0; // Data testimonial const testimonials = [ { stars: 5, comment: "It was such as a great choice <br>to invest in the reliable systems that BankMo has provide for me.", name: "Amanda", role: "Sr Credit Analyst", image: "assets/images/photos/profile-picture.png" }, { stars: 5, comment: "BankMo's reliable systems are truly exceptional and easy to use.", name: "John", role: "Financial Advisor", image: "assets/images/photos/profile-picture.png" }, { stars: 5, comment: "I am very satisfied with the reliable systems provided by BankMo.", name: "Sarah", role: "Investment Manager", image: "assets/images/photos/profile-picture.png" } ]; function renderTestimonial(index, direction) { const testimonial = testimonials[index]; testimonialContainer.innerHTML = ` <div class="flex flex-col items-center w-full flex-none ${direction === 'next' ? 'slide-in-right' : 'slide-in-left'}"> <div class="flex gap-x-[6px] md:gap-x-[14px]"> ${Array.from({ length: testimonial.stars }, () => `<img src="assets/images/icons/star.svg" alt="Star" class="w-[18px] h-[18px] md:w-[22px] md:h-[22px] shrink-0">`).join('')} </div> <div class="mt-[30px] px-[20px] 2xl:px-[211px]"> <p class="text-[14px] sm:text-[24px] 2xl:text-[40px] 2xl:leading-[70px] text-center">${testimonial.comment.replace( /reliable systems/g, '<span class="font-semibold">reliable systems</span>' )}</p> </div> <div class="mt-[20px] md:mt-[30px] flex items-center gap-[12px] md:gap-x-[24px]"> <div class="w-[50px] h-[50px] md:w-[80px] md:h-[80px] border border-[#78839E] rounded-full flex items-center justify-center"> <img src="${testimonial.image}" alt="${testimonial.name}" class="w-[40px] h-[40px] md:w-[70px] md:h-[70px] rounded-full object-cover object-center shrink-0"> </div> <div> <p class="text-[16px] md:text-[20px] font-medium text-[#13214A]">${testimonial.name}</p> <p class="text-[12px] md:text-[16px] text-[#77809D]">${testimonial.role}</p> </div> </div> </div> `; } function slide(direction) { testimonialContainer.classList.remove('slide-in-right', 'slide-in-left'); currentIndex = direction === 'next' ? (currentIndex + 1) % testimonials.length : (currentIndex - 1 + testimonials.length) % testimonials.length; renderTestimonial(currentIndex, direction); } prevButton.addEventListener('click', () => slide('prev')); nextButton.addEventListener('click', () => slide('next')); renderTestimonial(currentIndex, 'next'); }); Kode ini membuat komponen testimonial interaktif dengan navigasi kiri–kanan dan animasi transisi. Data Testimonial: Disimpan dalam array berisi nama, peran, komentar, bintang, dan foto.Navigasi: Dua tombol (prevButton dan nextButton) digunakan untuk berpindah testimonial.Fungsi Utama:renderTestimonial(index, direction): Menampilkan testimonial berdasarkan indeks dan menambahkan animasi (slide-in-left atau slide-in-right).slide(direction): Mengatur indeks aktif lalu memanggil renderTestimonial.Inisialisasi: Saat halaman dimuat, testimonial pertama langsung ditampilkan. Ketika sudah menambahkan fungsionalitas dengan menggunakan JavaScript, maka selanjutnya adalah membuat efek slide menggunakan CSS. /* Animasi fade */ @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } /* Animasi slide dari kanan */ @keyframes slideInRight { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } } /* Animasi slide dari kiri */ @keyframes slideInLeft { from { transform: translateX(-100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } } /* Class untuk animasi */ .fade-in { animation: fadeIn 0.5s ease-in-out; } .slide-in-right { animation: slideInRight 0.5s ease-in-out; } .slide-in-left { animation: slideInLeft 0.5s ease-in-out; } fadeIn: Mengubah opacity dari 0 (transparan) menjadi 1 (tidak transparan) dalam 0.5 detik.slideInRight: Membuat elemen bergeser dari luar layar kanan (menggunakan translateX(100%)) ke posisi normal sambil mengubah opacity dari 0 ke 1.slideInLeft: Membuat elemen bergeser dari luar layar kiri (menggunakan translateX(-100%)) ke posisi normal sambil mengubah opacity dari 0 ke 1..fade-in: Menerapkan animasi fade..slide-in-right: Menerapkan animasi slide dari kanan..slide-in-left: Menerapkan animasi slide dari kiri. Finalisasi dan Deploy Setelah selesai membuat semua section, maka hal terakhir yang kita lakukan adalah push ke repository github. Sebelum mengupload proyek ke GitHub, kita perlu melakukan setup terlebih dahulu agar file atau folder yang tidak penting, seperti node_modules, tidak ikut terupload. Langkah pertama adalah membuka atau membuat file .gitignore, lalu tambahkan nama file atau folder yang ingin dikecualikan dari proses upload ke GitHub. VSCode - Ignore Node Module 1. Membuat Repository Baru Langkah pertama yang kita lakukan adalah membuat repository baru untuk menampung seluruh kode yang sudah dibuat sebelumnya. Github - New repository 2. Menghubungkan Projek ke Repository Github - New repository Langkah-langkah Upload Project ke GitHub Buka terminal di folder project kamu.Jalankan perintah-perintah berikut secara berurutan:Inisialisasi Git: git initUbah nama branch default ke main: git branch -m mainTambahkan remote repository (ganti username dengan username GitHub kamu): git remote add origin <https://github.com/username/BankMo-Project.git>Tambahkan semua file ke staging: git add .Commit dengan pesan: git commit -m "Initial commit"Push ke GitHub: git push -u origin mainSetelah selesai, cek repository kamu di GitHub untuk memastikan file sudah terupload dengan benar. Github - Repository 3. Deploy Projek ke Vercel Langkah Terakhir adalah deploy projek agar projek bisa diakses secara online oleh semua orang. Hal yang perlu disiapkan : Login vercel.com dan hubungkan ke akun Github.Add New Project Vercel - Homepage Pilih Repository Vercel - For Import Setup nama dan Root Directory, arahkan ke folder src karena file index.html berada di dalamnnya. Vercel - New Proyek Jika selesai maka klik Deploy lalu akan diarahkan ke halaman Dashboard Projek. Vercel - Uploaded Projek siap diakses secara Online melalui link yang sudah tertera di Dashboard.bankmobwa.vercel.app Penutup Mengubah desain Figma menjadi HTML menggunakan Tailwind CSS dan JavaScript merupakan langkah penting dalam proses pengembangan web modern. Pendekatan ini tidak hanya memastikan konsistensi antara desain dan produk akhir, tetapi juga mempercepat proses pengembangan berkat utilitas Tailwind yang siap pakai serta fleksibilitas dari JavaScript. Melalui panduan ini, kita telah mempelajari bagaimana mentransformasikan desain dari Figma menjadi halaman web yang fungsional dengan bantuan Tailwind CSS dan JavaScript. Teruslah bereksperimen dengan komponen yang lebih kompleks dan optimalkan alur kerja (workflow) kamu. Selamat mencoba, semoga proses pengembanganmu menjadi lebih efisien dan menyenangkan!

Kelas Slicing Figma to HTML dengan Tailwind CSS - Login Page di BuildWithAngga

Slicing Figma to HTML dengan Tailwind CSS - Login Page

Slicing Figma to HTML dengan Tailwind CSS - Login Page Pernah lihat desain keren di Figma dan bingung mulai dari mana untuk nge-slice jadi HTML? Artikel ini bakal kasih contoh step-by-step nyusun layout login page modern pakai Tailwind CSS. Kita mulai dari satu kasus nyata: sebuah desain halaman login yang sudah siap di Figma dan tinggal dikonversi ke HTML fungsional. Nah, di sinilah proses slicing berperan penting—mengubah desain visual menjadi tampilan nyata menggunakan Tailwind CSS versi 4. Dengan pendekatan utility-first Tailwind, kita bisa membangun antarmuka yang cepat, konsisten, dan efisien. Dalam tutorial ini, kita akan pelajari langkah-langkah melakukan slicing Figma ke HTML untuk halaman login, dimulai dari persiapan file desain, penyusunan struktur HTML, hingga penerapan utility classes yang tepat. Panduan ini ditujukan untuk siapa saja yang ingin mengefisienkan proses konversi desain ke kode menggunakan Tailwind CSS V4. Yuk kita mulai! Menyiapkan desain figma dan instalasi tailwind Sebelum mulai proses slicing, pastikan semua bahan sudah siap. Kalian bisa membuka desain halaman login di Figma yang dapat di download melalui Shaynakit dan langsung mengekspor aset yang dibutuhkan, seperti logo atau ilustrasi, sesuai kebutuhan layout. Untuk icon disarankan export sebagai .svg dan untuk gambar bisa .png. Untuk Tailwind CSS, ada dua opsi: gunakan CDN untuk setup cepat, atau instal menggunakan Tailwind CLI dengan mengikuti dokumentasi resminya. Pilih metode yang paling sesuai dengan workflow kalian. Setelah aset diekspor, simpan ke dalam folder assets/images/ sesuai struktur proyek. Jika kalian menggunakan struktur folder sendiri, pastikan untuk menyesuaikan path file-nya agar tidak terjadi error saat implementasi di HTML. Contoh struktur folder yang digunakan. Slicing Figma to Html Setelah file dan setup Tailwind CSS siap, langkah berikutnya adalah memastikan semuanya berjalan dengan baik. Coba jalankan contoh template HTML dasar dari dokumentasi Tailwind di browser untuk memastikan Tailwind sudah terintegrasi dengan benar. Jika semuanya sudah berfungsi sebagaimana mestinya, saatnya kita mulai proses slicing. Kita akan mulai menyusun struktur HTML sesuai desain login page dari Figma. Layout dan style dasar Sebelum masuk ke layout, kita perlu mengatur tampilan dasar yang berlaku secara global—semacam style fondasi untuk seluruh halaman. Mulai dari font-family, warna latar belakang, warna teks, hingga pengaturan dasar pada elemen <body>. Ini penting supaya tampilan antarmuka tetap konsisten dengan desain Figma. body { font-family: "Lexend Deca", sans-serif; background-color: #F3F5F9; color: #292D32; } Style di atas disesuaikan langsung dari desain Figma—baik jenis font, warna latar, maupun warna teks utama. Selanjutnya, kita modifikasi file index.html agar tampak seperti berikut: <!doctype html> <html> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link href="./output.css" rel="stylesheet" /> <!-- Load font Lexend Deca dari Google Fonts --> <link rel="preconnect" href="https://fonts.googleapis.com" /> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <link href="https://fonts.googleapis.com/css2?family=Lexend+Deca:[email protected]&display=swap" rel="stylesheet" /> </head> <body> <div class="flex"> <!-- Komponen login akan ditempatkan di sini --> </div> </body> </html> Di bagian <head>, kita menambahkan CDN untuk mengimpor font Lexend Deca dari Google Fonts. Sementara itu, <div class="flex"> akan menjadi wadah utama tempat semua komponen login disusun nantinya. Membuat halaman login Jika kita perhatikan desain di Figma, bagian kiri halaman login berisi elemen visual berupa teks dan gambar dekoratif. Elemen ini berfungsi sebagai pemanis dan pengisi ruang kosong, memberikan kesan profesional pada layout. Untuk membuatnya, kita akan membagi area tersebut menjadi dua bagian utama: Teks bagian atas — terdiri dari heading dan subheading.Container gambar — sebagai elemen visual di bagian bawah. Mulailah dengan struktur HTML dasar berikut: <div class="flex flex-col"> <p>— Manage Stock and Merchants</p> <p>Optimized Inventory,<br />Effortless Workflow 🎯</p> <div> <img src="" alt="image" /> </div> </div> Tampilan konten awal. Selanjutnya, kita akan menambahkan kelas Tailwind CSS sesuai dengan desain yang ada di Figma. Berikut tampilan akhir dari parent container-nya: <div class="flex flex-col h-screen overflow-hidden rounded-tr-[32px] pl-[30px] pt-[46px] w-[685px] shrink-0 bg-[linear-gradient(336.99deg,#0a3a89_0%,#1053d5_100%)]"> Tambahkan juga styling pada teks agar sesuai dengan desain: <p class="font-semibold text-lg text-[#deff6e]">— Manage Stock and Merchants</p> <p class="font-extrabold text-[42px] uppercase text-white mt-4 mb-[30px]"> Optimized Inventory,<br /> Effortless Workflow 🎯 </p> Jika diimplementasikan dengan benar, tampilannya akan menyerupai desain berikut: Tampilan bagian kiri setelah diberi style. Menambahkan gambar Selanjutnya, kita masuk kebagian gambar. Export gambar dengan settingan PNG dengan resolusi 3x agar kualitas gambar tetap terjaga dan tajam walau dilihat pada layar dengan resolusi lebih tinggi dari design figma, atau teman teman bisa mendownloadnya dari link asset yang sudah disedaikan sebelumnya. berikut contohnya. Untuk bagian gambar, ekspor langsung dari Figma dalam format PNG dengan resolusi 3x agar tampil tajam bahkan di layar beresolusi tinggi. Simpan gambar ke dalam folder assets/images/backgrounds/ agar lebih mudah dikelola. Gunakan gambar tersebut di HTML dengan struktur berikut: export gambar tersebut kedalam folder assets/iamges/backgrounds agar kita mudah menemukannya. pada index.html. Gunakan gambar tersebut kemudian berikan style pada container gambar itu seperti dibawah ini. <div class="flex flex-1 overflow-hidden rounded-tl-[20px]"> <img src="assets/images/backgrounds/bg-image-1.png" alt="image" /> </div> Namun, kamu mungkin akan mengalami masalah pada tampilan saat layar berbeda ukurannya dari desain Figma. Contohnya seperti ini: Tampilan setelah diberi gambar dan kondisi gambar tidak responsive. Kiri: Gambar terlalu kecil karena tinggi container disesuaikan.Kanan: Gambar tertarik secara vertikal hingga tampak distorted. Untuk mengatasi ini, tambahkan class Tailwind berikut pada elemen <img>: <img src="assets/images/backgrounds/bg-image-1.png" class="size-full object-cover object-left-top" alt="image"> Dengan object-cover, gambar akan selalu menutupi seluruh container tanpa distorsi, meskipun sebagian sisi gambar mungkin terpotong. Hasil akhirnya akan seperti ini: Tampilan gambar setelah diberikan style agar responsive. Walaupun sebagian gambar terpotong, tampilannya tetap bersih, proporsional, dan tidak terlihat pecah ataupun memanjang secara tidak wajar. Form login Sekarang kita akan masuk ke bagian yang lebih kompleks: form login. Jika kita lihat desain di Figma, ada perbedaan tampilan pada elemen input ketika sudah diisi dan ketika kosong. Selain itu, juga ada fitur untuk melihat password yang diketik. Jangan khawatir, kita akan bahas semuanya secara detail untuk membuat desain ini sesuai dengan yang ada di Figma. Yuk, kita mulai! Seperti pada bagian sebelumnya, kita akan menambahkan struktur elemen HTML. Namun kali ini, beberapa elemen sudah memiliki style default yang cukup sederhana agar tutorial ini tidak terlalu panjang atau membosankan. <div class="flex flex-1 items-center justify-center"> <form action="overview.html" class="flex flex-col w-[435px] shrink-0 rounded-3xl gap-10 p-6 bg-white"> <img src="assets/images/logos/logo.svg" class="w-[203px] mx-auto" alt="logo" /> <div class="flex flex-col gap-[30px]"> <div class="flex flex-col gap-3 text-center"> <p class="font-semibold text-2xl">Hey🙌🏻, Welcome Back!</p> <p class="font-medium text-[#6a7686]">Login to your account to continue!</p> </div> <div id="Input-Container" class="flex flex-col gap-4 w-full"> <!-- Input --> <p class="font-medium text-sm text-[#6a7686]"> Forget Password? <a href="#" class="font-semibold text-[#1053d5] hover:underline">Reset Password</a> </p> </div> <button type="submit" class="btn btn-primary w-full font-bold">Sign In</button> </div> </form> </div> Jika sudah mengikuti langkah ini, tampilan form login seharusnya terlihat seperti gambar berikut: Tampilan form login pada bagian kanan. Menambahkan input email Sekarang, mari kita fokus pada elemen input. Kita mulai dengan membuat input untuk email. Berikut struktur dasar HTML untuk input email: <label> <div> <img src="assets/images/icons/sms-grey.svg" class="flex size-6 shrink-0" alt="icon" /> </div> <p class="placeholder">Your email address</p> <input type="email" class="" placeholder="" /> </label> Penjelasan: Label: Semua elemen input dibungkus dalam elemen <label> agar saat area input diklik, kita bisa langsung fokus dan mulai mengetik.Icon: Kita letakkan ikon di dalam div terpisah dan posisikan secara absolute agar tetap konsisten di posisi kiri input.Placeholder: Di desain Figma, placeholder akan berpindah ke atas ketika input terisi, sehingga kita menggunakan elemen terpisah untuk placeholder ini agar lebih mudah di-styling. Sekarang, kita tambahkan style pada elemen input tersebut agar sesuai dengan desain Figma: <label class="relative"> <div class="flex items-center pr-4 absolute transform -translate-y-1/2 top-1/2 left-6 border-r-[1.5px] border-[#e8e8e8]"> <img src="assets/images/icons/sms-grey.svg" class="flex size-6 shrink-0" alt="icon" /> </div> <p class="placeholder font-medium text-[#6a7686] text-sm absolute -translate-y-1/2 left-[81px] top-1/2"> Your email address </p> <input type="email" class="appearance-none w-full h-[72px] font-semibold text-lg rounded-3xl border-[1.5px] border-[#e8e8e8] pl-20 pr-6 pb-[14.5px] pt-[14.5px]" placeholder="" /> </label> Penjelasan Styling: Label: Diberikan class .relative agar elemen-elemen di dalamnya bisa diposisikan relatif terhadap label.Icon: Gambar ikon diletakkan dengan menggunakan class absolute, diatur di sebelah kiri input dengan border separator.Placeholder: Diberikan class absolute untuk memindahkan posisi placeholder ke atas saat input terisi, menggunakan warna dan ukuran teks sesuai dengan desain.Input Field: Input email diberi styling agar sesuai dengan desain Figma, menggunakan border, padding, dan font yang konsisten. Dengan penerapan tersebut, tampilan input email akan seperti berikut: Tampilan input email tahap awal. Mengatasi Masalah Placeholder yang Tindih namun ada masalah ketika ada input dari user, placeholder dan input saling tindih tidak seperti pada design figma. berikut solusinya, pertama kita akan menggunakan fitur “group” dari tailwind css. Fitur ini memungkinkan kita untuk mengatur style berdasarkan kondisi atau state dari child dalam suatu group atau untuk group itu sendiri. Langkah pertama adalah tambahkan .group ke <label> seperti contoh berikut Sebelumnya kita sudah menambahkan elemen input untuk email, namun ada masalah saat pengguna mulai mengetik—placeholder dan teks input saling tumpang tindih, yang tidak sesuai dengan desain Figma. Untuk mengatasi masalah ini, kita akan menggunakan fitur “group” dari Tailwind CSS. Fitur ini memungkinkan kita untuk mengatur style berdasarkan kondisi atau state dari child dalam suatu group, atau untuk group itu sendiri. Langkah pertama adalah menambahkan class .group ke elemen <label> untuk membuat semua child element dari label tersebut menjadi satu group. <label class="group relative"> Dengan menggunakan class .group, kita bisa menerapkan style kondisional pada elemen di dalamnya berdasarkan state grup tersebut. Menambahkan Transisi untuk Placeholder Untuk memastikan placeholder bergerak dengan mulus saat pengguna mulai mengetik, kita perlu mengatur posisi top placeholder agar bisa berubah. Kita akan memanfaatkan fitur Tailwind placeholder-shown: untuk mendeteksi apakah elemen input sedang kosong atau sudah diisi. Namun, karena kita menggunakan elemen <p> untuk placeholder (bukan atribut placeholder pada <input>), kita akan menggabungkan group-has-placeholder-shown: untuk mendeteksi perubahan pada elemen input di dalam grup tersebut. Berikut solusinya untuk elemen placeholder: <p class="placeholder font-medium text-[#6a7686] text-sm absolute -translate-y-1/2 left-[81px] top-[25px] group-has-placeholder-shown:top-1/2 transition-all duration-300"> Your email address </p> Perubahan yang kita buat: Ganti class top-1/2 menjadi top-[25px] group-has-placeholder-shown:top-1/2, agar posisi default placeholder berada di 25px, yaitu posisi saat placeholder geser ke atas. Namun, selama input belum menerima inputan dari user, posisi top akan berada di 50% atau di tengah.Gunakan transition-all duration-300 untuk memberi efek transisi yang halus saat placeholder bergerak. Jika sudah sesuai, maka tampilan input saat user mulai mengetik akan terlihat seperti ini: Tampilan input email dengan placeholder yang sudah sesuai pada tempatnya. Menambahkan Transisi untuk Input Sekarang, mari kita atur padding pada elemen input agar teks input tidak bertabrakan dengan placeholder yang sudah dipindahkan. Kenapa padding? bukan top seperti elemen placeholder, hal ini dikarenakan elemen <input> memenuhi ruang <label> sehingga untuk menggeser text kebawah kita perlu mengubah paddingnya. Ubah elemen input menjadi seperti berikut: <input type="email" class="appearance-none w-full h-[72px] font-semibold text-lg rounded-3xl border-[1.5px] border-[#e8e8e8] pl-20 pr-6 pb-[14.5px] pt-[34.5px] placeholder-shown:pt-[14.5px] focus:border-[#292d32] transition-300" placeholder="" > Konsepnya masih sama dengan elemen .placeholder, namun disini yang kita ubah adalah padding untuk menggeser text inputan dari userke bawah. Tidak hanya itu, pada <input> kita juga tidak menggunakan group-has- karena cukup mendeteksi perbuhan dari elemen <input> itu sendiri dan tidak bergantung pada group. Jika sudah benar, maka tampilan input saat pengguna mengetik akan seperti berikut: Tampilan input email yang telah diberi style dan animasi sesuai figma. Menambahkan Input Password dan Fitur Menampilkan Password Sekarang kita akan menambahkan input password. Caranya hampir sama dengan input email, namun kita juga menambahkan tombol untuk melihat password yang diketik. Berikut adalah struktur HTML untuk input password: <label class="group relative"> <div class="flex items-center pr-4 absolute transform -translate-y-1/2 top-1/2 left-6 border-r-[1.5px] border-[#e8e8e8] "> <img src="assets/images/icons/lock-grey.svg" class="flex size-6 shrink-0" alt="icon"> </div> <p class="placeholder font-medium text-[#6a7686] text-sm absolute -translate-y-1/2 left-[81px] top-[25px] group-has-placeholder-shown:top-[36px] group-focus-within:top-[25px] transition-all duration-300"> Your password </p> <input id="passwordInput" type="password" class="appearance-none w-full h-[72px] font-semibold text-lg rounded-3xl border-[1.5px] border-[#e8e8e8] pl-20 pr-16 pb-[14.5px] pt-[34.5px] placeholder-shown:pt-[14.5px] focus:border-[#292d32] transition-300 tracking-[0.3em]" placeholder=""> <button id="togglePassword" type="button" class="absolute transform -translate-y-1/2 top-1/2 right-6"> <img src="assets/images/icons/eye-grey.svg" class="flex size-6 shrink-0" alt="icon"> </button> </label> Perubahan utama adalah penambahan tombol di sebelah kanan input untuk melihat password, serta padding tambahan pada input untuk memberi ruang bagi tombol tersebut. const passwordInput = document.getElementById('passwordInput'); const toggleBtn = document.getElementById('togglePassword'); toggleBtn.addEventListener('click', () => { const isPassword = passwordInput.type === 'password'; passwordInput.type = isPassword ? 'text' : 'password'; }); Simpan kode ini dalam file .js terpisah atau masukkan langsung di dalam tag <script> pada template HTML kita. Dengan komponen input yang sudah selesai, kita resmi menyelesaikan proses slicing form login sesuai desain di Figma—mulai dari struktur HTML, styling menggunakan Tailwind CSS, hingga interaksi dasar seperti placeholder dinamis dan toggle visibility pada password. Untuk saat ini, kita memang hanya fokus pada bagian frontend statis tanpa menyentuh responsif atau logika backend. Tapi dari sini, kamu sudah punya fondasi visual yang solid untuk melangkah lebih jauh jika dibutuhkan. Jangan ragu untuk eksplorasi atau sesuaikan lebih lanjut dengan kebutuhan project-mu. Tampilan akhir dari slicing figma to html halaman login. Penutup dan Saran Slicing desain Figma ke dalam bentuk HTML statis menggunakan Tailwind CSS memang terlihat sederhana, tapi sebenarnya mengajarkan banyak hal penting: mulai dari pemahaman struktur HTML yang rapi, teknik positioning yang presisi, hingga interaksi UI seperti placeholder dinamis dan fitur show/hide password. Dengan pendekatan ini, kamu sudah punya fondasi kuat untuk membangun antarmuka login yang profesional dan siap dikembangkan lebih lanjut, baik dari sisi responsif maupun backend-nya di kemudian hari. Namun, belajar secara mandiri tentu tidak selalu mudah—terkadang justru bikin frustrasi karena terlalu banyak hal teknis yang harus dikuasai sekaligus. Untuk itu, kami merekomendasikan kamu untuk belajar langsung bersama mentor expert di BuildWithAngga. Melalui program mentoring di BuildWithAngga, kamu bisa mendapatkan: ✅ Akses Materi Seumur Hidup – Belajar kapan pun tanpa batas waktu. ✅ Sertifikat Resmi – Validasi skill kamu di mata recruiter atau klien. ✅ Portfolio Nyata – Mengerjakan project dengan standar industri. ✅ Akses Komunitas dan Mentor – Diskusi langsung dengan praktisi yang berpengalaman. Jangan ragu untuk ambil langkah lebih jauh. Bangun fondasi yang kuat hari ini, dan siapkan dirimu untuk tantangan yang lebih besar di dunia web development. 🚀

Kelas Slicing Figma ke HTML: Halaman Pilih Kursi Pesawat Dengan Tailwind CSS di BuildWithAngga

Slicing Figma ke HTML: Halaman Pilih Kursi Pesawat Dengan Tailwind CSS

Slicing desain dari Figma ke HTML kelihatannya simpel — susun elemen, pasang teks, selesai. Tapi saat ketemu detail kecil seperti spasi antar elemen dan struktur grid, baru terasa semakin kompleks. Di artikel ini, kita bakal belajar bareng tentang slicing halaman pilih kursi pesawat dari Figma ke HTML menggunakan Tailwind CSS. Layout-nya unik: dua sisi kursi dengan jalan kosong di tengah, jadi tidak bisa asal pakai grid standar. Kita akan susun semua ini cukup dengan satu halaman sederhana, tanpa tambahan macam-macam. Sebelum mulai slicing, ada baiknya kita pahami dulu struktur layout dari desain yang mau kita buat. Kita bisa download desain figma-nya melalui Shaynakit. Kalau asal langsung masuk bikin HTML, biasanya bakal kebingungan di tengah jalan — entah karena grid yang salah, spasi yang tidak pas, atau alignment yang mulai berantakan. Dengan ngerti dulu pola layout-nya, kita bisa susun struktur dasar HTML dan CSS lebih tenang, tanpa harus bolak-balik revisi. Memahami Layout dari Figma Sebelum mulai slicing ke HTML, kita perlu pahami dulu pola layout yang ada di desain. Tampilan halaman pada design figma. Ini penting supaya struktur yang kita buat nanti tidak asal tumpuk dan gampang diatur. Kalau dilihat dari desain Figma-nya, layout halaman pilih kursi ini punya pola seperti ini: Ada dua sisi utama: sisi kiri dan sisi kanan pesawat.Masing-masing sisi punya dua kolom kursi.Di tengah-tengah ada spasi kosong yang berfungsi sebagai jalan antar kursi. Kalau dihitung, satu baris akan terdiri dari empat kursi, tapi tidak sejajar penuh karena ada ruang kosong di tengah. Artinya, kalau kita langsung pakai grid biasa (seperti grid-cols-4), jarak antar kursi akan terlalu rapat dan jalan di tengah tidak akan terlihat. Juga, kalau kita pakai grid-cols-5 maka setiap kolom akan punya lebar yang sama dan akan terlihat kurang proporsional jika dibandingkan dengan desain figma. Kita perlu bikin trik tambahan supaya ada "spacer" di antara dua sisi kursi ini. Menyusun Struktur HTML Dasar Setelah memahami pola layout dari desain, sekarang kita mulai susun struktur HTML dasarnya. Untuk setup awal, kita sudah siapkan file index.html sederhana dengan Tailwind CSS dan font Poppins dari Google Fonts. Berikut struktur dasarnya: <!doctype html> <html> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script> <!-- font Poppins --> <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700;800;900&display=swap" rel="stylesheet" /> </head> <body class="font-['Poppins'] bg-[#dae1e9]"> <div id="Mobile-Layout-Container" class="w-full max-w-[640px] min-w-0 overflow-x-hidden mx-auto min-h-screen relative bg-[#FAFAFA]"> <!-- Content --> </div> </body> </html> Penjelasan singkat: Tailwind CSS kita load menggunakan CDN supaya lebih simple.Font Poppins langsung dipasang di <head>, dan dipakai lewat Tailwind font-['Poppins'].Background warna abu-abu muda (bg-[#dae1e9]) untuk area luar.Container utama (#Mobile-Layout-Container) dibuat responsif hanya di lebar tertentu, supaya desain tetap terpusat dan konsisten.Konten halaman nantinya akan kita taruh di dalam <div id="Mobile-Layout-Container">...</div> ini. Untuk saat ini, struktur ini cukup dan siap dipakai buat membangun layout kursi pesawat. Membuat Bagian Judul dan Keterangan Status Kursi Sebelum membangun layout kursi, kita tambahkan dulu elemen header di bagian atas. Header ini berfungsi untuk menampilkan judul halaman dan informasi status kursi yang tersedia. Berikut struktur HTML yang akan kita gunakan: <h1 class="font-semibold text-2xl text-[#1F1449] pt-[30px] mx-6">Select Your <br> Favorite Seat</h1> <div class="flex items-center gap-[10px] mt-[30px] mx-6"> <div class="flex items-center gap-[6px]"> <div class="flex shrink-0 size-4 rounded-[6px] border border-[#5C40CC] bg-[#E0D9FF]"></div> <span class="text-sm">Available</span> </div> <div class="flex items-center gap-[6px]"> <div class="flex shrink-0 size-4 rounded-[6px] border border-[#5C40CC] bg-[#5C40CC]"></div> <span class="text-sm">Selected</span> </div> <div class="flex items-center gap-[6px]"> <div class="flex shrink-0 size-4 rounded-[6px] bg-[#EBECF1]"></div> <span class="text-sm">Unavailable</span> </div> </div> Penjelasan singkat: Judul halaman ditampilkan menggunakan elemen <h1>.Keterangan status kursi menggunakan kombinasi flex untuk membuat item sejajar horizontal.Setiap status memiliki:Kotak kecil berwarna (untuk indikator visual)Label teks di sebelahnya Semua styling sudah menggunakan kelas bawaan Tailwind, jadi bisa langsung digunakan tanpa tambahan kustomisasi lagi. Jika semua sudah benar, maka tampilan kita akan terlihat seperti ini Tampilan hasil code HTML header. Membuat Seat Map (Tahap 1): Struktur Dasar dan Baris Pertama Setelah bagian header beres, sekarang kita mulai bangun seat map. Karena strukturnya unik (dua sisi dengan jalan di tengah), kita akan susun perlahan — dimulai dari container utama, label baris, dan satu baris kursi. 1. Container Seat Map Pertama, kita butuh sebuah container untuk membungkus seluruh bagian seat map ini. Kita akan pakai elemen <form> karena nanti seat ini bisa dikaitkan ke proses submit (meskipun sekarang belum ada backend-nya). <form action="" class="mt-[30px]"> <div class="flex flex-col mx-6 gap-[30px] w-auto h-fit rounded-[18px] bg-white py-[30px] px-[22px]"> <div class="flex flex-col gap-4"> <!-- Seat content di sini --> </div> <div class="flex flex-col gap-4"> <!-- Keterangan pilihan di sini --> </div> </div> <!-- Button submit --> </form> 2. Label Kolom Kursi (A, B, C, D) Di dalam form, kita mulai dengan baris label yang menunjukkan kolom kursi: A, B (sisi kiri), dan C, D (sisi kanan). Di tengah-tengah kita beri elemen kosong sebagai spacer, seolah-olah itu adalah lorong pesawat. <div id="Seat-Column" class="row flex flex-row justify-evenly"> <div class="grid grid-cols-2 gap-4"> <div class="flex items-center justify-center h-6 w-12 shrink-0"> <span class="text-[#9698A9]">A</span> </div> <div class="flex items-center justify-center h-6 w-12 shrink-0"> <span class="text-[#9698A9]">B</span> </div> </div> <div class="spacer w-12 flex shrink-0 text-[#9698A9] flex items-center justify-center"></div> <div class="grid grid-cols-2 gap-4"> <div class="flex items-center justify-center h-6 w-12 shrink-0"> <span class="text-[#9698A9]">C</span> </div> <div class="flex items-center justify-center h-6 w-12 shrink-0"> <span class="text-[#9698A9]">D</span> </div> </div> </div> Tampilan keterangan kolom kursi. 3. Satu Baris Kursi (Baris 1) Setelah label kolom, kita buat satu baris kursi. Strukturnya sama seperti sebelumnya — dua grid kiri dan kanan dengan spacer di tengah. <div class="row flex flex-row justify-evenly"> <div class="grid grid-cols-2 gap-4"> <!-- Kursi A1 dan B1 --> <label class="group relative flex items-center justify-center size-12 shrink-0 rounded-[15px] overflow-hidden bg-[#E0D9FF] border-2 border-[#5C40CC] has-[:checked]:border-0 has-[:checked]:bg-[#5C40CC] has-[:disabled]:border-0 has-[:disabled]:bg-[#EBECF1] transition-all duration-300"> <input type="checkbox" name="seat" class="absolute inset-0 opacity-0"> <span class="font-semibold text-sm text-white opacity-0 group-has-[:checked]:opacity-100 transition-all duration-300">YOU</span> </label> <label class="group relative flex items-center justify-center size-12 shrink-0 rounded-[15px] overflow-hidden bg-[#E0D9FF] border-2 border-[#5C40CC] has-[:checked]:border-0 has-[:checked]:bg-[#5C40CC] has-[:disabled]:border-0 has-[:disabled]:bg-[#EBECF1] transition-all duration-300"> <input type="checkbox" name="seat" class="absolute inset-0 opacity-0"> <span class="font-semibold text-sm text-white opacity-0 group-has-[:checked]:opacity-100 transition-all duration-300">YOU</span> </label> </div> <div class="spacer w-12 flex shrink-0 text-[#9698A9] flex items-center justify-center"> 1 </div> <div class="grid grid-cols-2 gap-4"> <!-- Kursi C1 dan D1 --> <label class="group relative flex items-center justify-center size-12 shrink-0 rounded-[15px] overflow-hidden bg-[#E0D9FF] border-2 border-[#5C40CC] has-[:checked]:border-0 has-[:checked]:bg-[#5C40CC] has-[:disabled]:border-0 has-[:disabled]:bg-[#EBECF1] transition-all duration-300"> <input type="checkbox" disabled name="seat" class="absolute inset-0 opacity-0"> <span class="font-semibold text-sm text-white opacity-0 group-has-[:checked]:opacity-100 transition-all duration-300">YOU</span> </label> <label class="group relative flex items-center justify-center size-12 shrink-0 rounded-[15px] overflow-hidden bg-[#E0D9FF] border-2 border-[#5C40CC] has-[:checked]:border-0 has-[:checked]:bg-[#5C40CC] has-[:disabled]:border-0 has-[:disabled]:bg-[#EBECF1] transition-all duration-300"> <input type="checkbox" name="seat" class="absolute inset-0 opacity-0"> <span class="font-semibold text-sm text-white opacity-0 group-has-[:checked]:opacity-100 transition-all duration-300">YOU</span> </label> </div> </div> 4. Kenapa Pakai <label> + input type="checkbox"? Setiap kursi dibuat dengan struktur <label> yang membungkus <input type="checkbox">. Kenapa? Karena: Dengan <label>, kita bisa klik elemen visual (kursi) dan otomatis aktifkan checkbox-nya.Checkbox ini kita sembunyikan (opacity-0), dan hanya dipakai untuk nyimpan status “selected” secara visual.Style akan berubah sesuai status :checked atau :disabled. 5. Styling Dinamis: has-[:checked] dan group-has-[] Tailwind punya fitur CSS parent selector yang powerful. Di sini kita pakai dua hal: ✅ has-[:checked] Digunakan langsung di elemen label.Artinya: kalau input di dalamnya checked, ubah style si label.Contoh: has-[:checked]:bg-[#5C40CC] ✅ group + group-has-[:checked] Kita pakai ini untuk ubah style anak elemen (span teks “YOU”) kalau input di dalam label checked.group ada di label, group-has-[] ada di dalamnya.Contoh: <span class="group-has-[:checked]:opacity-100">YOU</span> 6. Kursi Unavailable Kita juga tambahkan atribut disabled ke input untuk kursi yang tidak tersedia. Tailwind akan baca has-[:disabled] dan ubah warnanya jadi abu-abu (seperti di desain). 7. Menambah bagian keterangan pilihan Seat map sudah selesai kita buat, sekarang kita tambah bagian keterangan. bagian ini akan menunjukan nomor kursi yang dipilih dan juga total harga yang ahrus dibayar. <div class="flex items-center justify-between"> <p class="font-light text-sm text-[#9698A9]">Your seat</p> <p class="text-[#1F1449]">A1, D2</p> </div> <div class="flex items-center justify-between"> <p class="font-light text-sm text-[#9698A9]">Total</p> <p class="font-semibold text-[#5C40CC]">$50,250</p> </div> Preview Layout Tampilan komponen pilih kursi yang sudah jadi. Menambahkan Tombol Submit di Bawah Layar Setelah semua elemen kursi selesai ditampilkan, sekarang kita tambahkan tombol untuk mengonfirmasi pilihan kursi. Tapi bukan sembarang tombol — kita ingin tombol ini selalu terlihat di bagian bawah layar, tanpa harus scroll-scroll ke bawah lagi. Untuk itu, kita gunakan position: fixed dan menempatkan tombol dengan: <div class="relative w-full mt-[30px] h-[101px] px-6"> <div class="fixed bottom-[46px] max-w-[640px] w-full transform -translate-x-1/2 left-1/2 px-6"> <button type="submit" class="w-full rounded-full text-center h-[55px] bg-[#5C40CC] text-white align-middle font-medium text-lg">Select Payment</button> </div> </div> Cara ini bikin tombol selalu nempel di bagian bawah layar, pas di tengah, dan tetap berada di dalam lebar maksimal layout (640px). Tombolnya dibungkus dengan <div> yang punya relative layout agar tetap konsisten kalau suatu saat kamu mau tambahkan elemen lain di bawahnya. Dan jangan lupa: walau posisinya fixed, tombol ini masih di dalam tag <form> supaya tetap bisa submit data nantinya. Tampilan jika semua elemen sudah selesai di-slicing Membuat Kursi Secara Dinamis dengan JavaScript Setelah kita lihat struktur HTML awal untuk baris kursi, mungkin sudah mulai terasa satu hal: kalau kita harus tulis manual satu per satu, bakal makan waktu dan nyusahin banget. Makanya, di bagian ini kita akan mulai pakai JavaScript untuk bikin seat map-nya secara dinamis. Tapi supaya seat-nya bisa dirender lewat JS, kita perlu sediakan dulu tempat penampungnya di HTML. Kita hapus dulu elemen <div class="row ..."> yang sebelumnya kita hardcode, dan ganti dengan elemen kosong seperti ini: <div id="Seat-Wrapper" class="flex flex-col gap-4"></div> Elemen ini akan kita jadikan target untuk inject baris-baris kursi nantinya. Jadi alur kerjanya, JavaScript akan melakukan looping berdasarkan data kursi, lalu menyusun elemen HTML kursinya, dan akhirnya menampilkannya ke dalam #Seat-Wrapper. Dengan pendekatan ini, kita bisa kontrol seat map lebih fleksibel — entah itu buat nambah jumlah kursi, menandai yang unavailable, atau nunjukin kursi yang dipilih. Sekarang kita masuk ke tahap bikin looping untuk render kursi secara dinamis pakai JavaScript. Tujuannya jelas: biar kita tidak nulis <label> seat satu-satu secara manual — repot dan rawan typo. Dengan data sederhana berupa array nested, kita bisa buat struktur kursi otomatis, lengkap dengan spacer di tengah. Berikut paragraf penjelasan + contoh kodenya yang bisa kamu pakai: Supaya lebih fleksibel dan tidak perlu nulis elemen satu per satu, sekarang kita akan membuat seat map-nya dengan JavaScript. Caranya: kita buat dulu struktur data yang mewakili posisi kursi, lalu render ke DOM pakai loop. Sebagai contoh, kita bisa bikin array seperti ini: const seatRows = [ ['A1', 'B1', 'C1', 'D1'], ['A2', 'B2', 'C2', 'D2'], ['A3', 'B3', 'C3', 'D3'], // Tambah terus sesuai jumlah baris ]; Lalu kita looping setiap baris dan bagi jadi dua sisi (kiri dan kanan), dengan spacer di tengah: const seatContainer = document.querySelector('#Seat-Wrapper'); seatRows.forEach(row => { const rowDiv = document.createElement('div'); rowDiv.className = 'row flex flex-row justify-evenly'; const leftSide = document.createElement('div'); leftSide.className = 'grid grid-cols-2 gap-4'; row.slice(0, 2).forEach(seat => { leftSide.appendChild(createSeatElement(seat)); }); const spacer = document.createElement('div'); spacer.className = 'spacer w-12 flex shrink-0 text-[#9698A9] flex items-center justify-center'; spacer.textContent = row[0].replace(/\D/g, ''); // ambil angka baris dari seat (misal '1' dari 'A1') const rightSide = document.createElement('div'); rightSide.className = 'grid grid-cols-2 gap-4'; row.slice(2).forEach(seat => { rightSide.appendChild(createSeatElement(seat)); }); rowDiv.appendChild(leftSide); rowDiv.appendChild(spacer); rowDiv.appendChild(rightSide); seatContainer.appendChild(rowDiv); }); Fungsi createSeatElement ini bertugas bikin satu elemen <label> kursi sesuai style yang kita mau: function createSeatElement(label, disabled = false) { const wrapper = document.createElement('label'); wrapper.className = 'group relative flex items-center justify-center size-12 shrink-0 rounded-[15px] overflow-hidden bg-[#E0D9FF] border-2 border-[#5C40CC] has-[:checked]:border-0 has-[:checked]:bg-[#5C40CC] has-[:disabled]:border-0 has-[:disabled]:bg-[#EBECF1] transition-all duration-300'; const input = document.createElement('input'); input.type = 'checkbox'; input.name = 'seat'; input.className = 'absolute inset-0 opacity-0'; if (disabled) input.disabled = true; const span = document.createElement('span'); span.className = 'font-semibold text-sm text-white opacity-0 group-has-[:checked]:opacity-100 transition-all duration-300'; span.textContent = 'YOU'; wrapper.appendChild(input); wrapper.appendChild(span); return wrapper; } Dengan cara ini, kamu bisa dengan mudah nambah atau ubah barisan kursi cukup dari array-nya aja. Bahkan bisa diambil dari API nanti kalau memang perlu. Simpan kode JavaScript ini dalam file .js terpisah atau masukkan langsung di dalam tag <script> pada template HTML kita. Jika javascript sudah benar, maka tampilannya akan seperti ini. Tampilan hasil looping untuk membuat seat map. Dengan kode untuk looping kursi yang sudah selesai, kita hampir sampai pada bagian akhir proses slicing layout kursi pesawat sesuai desain Figma—dari struktur HTML, styling menggunakan Tailwind CSS, hingga interaksi dinamis menggunakan JavaScript. Untuk saat ini, kita memang hanya fokus pada bagian frontend statis, tanpa menyentuh responsif atau backend logic. Namun, dengan struktur ini, kita sudah punya dasar visual yang solid yang dapat dikembangkan lebih lanjut sesuai kebutuhan. Penutup dan Saran Proses slicing desain Figma ke dalam HTML menggunakan Tailwind CSS dan menambahkan interaksi dengan JavaScript ini memberikan kita banyak pelajaran penting. Mulai dari cara menyusun struktur HTML yang rapi, penggunaan Tailwind untuk styling secara efisien, hingga implementasi logika dinamis untuk memilih kursi—semua saling berinteraksi untuk membentuk tampilan yang lebih fungsional. Dengan pendekatan ini, kita telah membangun dasar yang kokoh untuk antarmuka pemilihan kursi yang siap dikembangkan lebih lanjut, baik untuk tambahan fitur interaktif maupun pengembangan backend di tahap berikutnya. Belajar membuat elemen dinamis ini memang menantang, dan mungkin ada saat-saat di mana kamu merasa stuck atau kesulitan. Tapi, jangan khawatir—setiap tantangan adalah kesempatan untuk mengasah kemampuan. Jika kamu merasa butuh bantuan lebih lanjut atau ingin memperdalam materi, jangan ragu untuk mencari mentor yang berpengalaman di BuildWithAngga. Program mentoring mereka menawarkan berbagai keuntungan: ✅ Akses Materi Seumur Hidup – Belajar kapan pun, tanpa batas waktu. ✅ Sertifikat Resmi – Validasi skill yang kamu kuasai. ✅ Portfolio Nyata – Kerjakan project dengan standar industri. ✅ Akses Komunitas dan Mentor – Diskusi langsung dengan praktisi yang sudah berpengalaman. Jangan takut untuk melangkah lebih jauh. Bangun fondasi yang kuat sekarang, dan siapkan dirimu menghadapi tantangan yang lebih besar di dunia web development. 🚀

Kelas Tutorial Laravel 12: Model, Migration, Seeder, Factory, Auth Sanctum, API, Postman di BuildWithAngga

Tutorial Laravel 12: Model, Migration, Seeder, Factory, Auth Sanctum, API, Postman

Laravel terus berkembang dengan fitur-fitur baru yang memudahkan pengembang dalam membangun aplikasi. Dengan dirilisnya Laravel 12, framework ini semakin optimal untuk membangun sistem manajemen konten (CMS) dan API backend. Berbagai pembaruan telah diterapkan agar proses pengembangan menjadi lebih cepat, efisien, dan sesuai dengan standar industri. Bagi para developer yang ingin membuat aplikasi berbasis web atau API dengan struktur yang rapi dan mudah dipelihara, Laravel 12 menjadi pilihan yang sangat menarik. Mempelajari Laravel 12 sebagai Backend Developer Pada artikel ini, kita akan mempelajari dasar-dasar coding Laravel 12 sebagai seorang backend developer. Fokus utama kita adalah memahami bagaimana framework ini digunakan untuk menangani berbagai aspek backend, seperti pengelolaan database, autentikasi pengguna, dan pengembangan API. Jika Anda ingin membangun sistem yang scalable dan mudah diintegrasikan dengan berbagai layanan lain, Laravel 12 menyediakan banyak fitur bawaan yang akan sangat membantu. Mari kita mulai perjalanan belajar Laravel 12 dengan memahami konsep-konsep dasarnya! Membuat Proyek Laravel 12 Tanpa Starter Kit dan Konfigurasi Database MySQL Untuk memulai proyek Laravel 12 tanpa menggunakan starter kit, pastikan Anda sudah menginstal Composer dan memiliki PHP versi terbaru. Berikut adalah langkah-langkahnya. 1. Membuat Proyek Laravel 12 Gunakan perintah berikut di terminal atau command prompt untuk membuat proyek baru: composer create-project laravel/laravel my-laravel12-app Perintah ini akan mengunduh dan menginstal Laravel 12 ke dalam folder my-laravel12-app. Setelah proses selesai, masuk ke dalam direktori proyek: cd my-laravel12-app 2. Mengatur File .env untuk Koneksi Database Buka file .env yang ada di root proyek dan ubah bagian konfigurasi database sesuai dengan pengaturan MySQL yang Anda gunakan. Contohnya: DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=nama_database DB_USERNAME=root DB_PASSWORD=yourpassword Jika Anda belum memiliki database, buat database baru dengan perintah SQL berikut di MySQL: CREATE DATABASE nama_database; Pastikan nama database di .env sama dengan yang Anda buat. 3. Menjalankan Migrasi Database Setelah konfigurasi database selesai, jalankan perintah berikut untuk membuat tabel-tabel default Laravel: php artisan migrate Jika terjadi error karena database belum terkoneksi dengan baik, pastikan MySQL berjalan dan periksa kembali pengaturan di file .env. 4. Menjalankan Proyek Laravel Untuk menjalankan aplikasi Laravel, gunakan perintah berikut: php artisan serve Setelah perintah ini dijalankan, Anda bisa mengakses aplikasi Laravel melalui browser di alamat: <http://127.0.0.1:8000> Dengan langkah-langkah di atas, proyek Laravel 12 sudah siap digunakan tanpa menggunakan starter kit. Anda bisa langsung mulai mengembangkan fitur sesuai kebutuhan. Membuat Model dan Migration Menggunakan Artisan Dalam Laravel, model dan migration digunakan untuk mengelola struktur database dengan lebih mudah. Berikut adalah cara membuat model dan migration untuk tabel Category, Course, dan User. 1. Membuat Model dan Migration Gunakan perintah berikut untuk membuat model beserta file migration-nya: php artisan make:model Category -m php artisan make:model Course -m php artisan make:model User -m Opsi -m akan membuat file migration secara otomatis untuk setiap model. 2. Menyesuaikan Migration Buka file migration yang ada di folder database/migrations dan edit sesuai kebutuhan. Migration untuk Category Buka file migration dengan nama yang mengandung create_categories_table dan ubah menjadi seperti berikut: use Illuminate\\Database\\Migrations\\Migration; use Illuminate\\Database\\Schema\\Blueprint; use Illuminate\\Support\\Facades\\Schema; return new class extends Migration { public function up() { Schema::create('categories', function (Blueprint $table) { $table->id(); $table->string('name'); $table->text('description')->nullable(); $table->timestamps(); }); } public function down() { Schema::dropIfExists('categories'); } }; Migration untuk Course Buka file migration dengan nama yang mengandung create_courses_table dan ubah menjadi seperti berikut: use Illuminate\\Database\\Migrations\\Migration; use Illuminate\\Database\\Schema\\Blueprint; use Illuminate\\Support\\Facades\\Schema; return new class extends Migration { public function up() { Schema::create('courses', function (Blueprint $table) { $table->id(); $table->string('title'); $table->text('description')->nullable(); $table->unsignedBigInteger('category_id'); $table->timestamps(); $table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade'); }); } public function down() { Schema::dropIfExists('courses'); } }; Migration untuk User Buka file migration dengan nama yang mengandung create_users_table dan ubah menjadi seperti berikut: use Illuminate\\Database\\Migrations\\Migration; use Illuminate\\Database\\Schema\\Blueprint; use Illuminate\\Support\\Facades\\Schema; return new class extends Migration { public function up() { Schema::create('users', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('email')->unique(); $table->string('password'); $table->timestamps(); }); } public function down() { Schema::dropIfExists('users'); } }; 3. Menjalankan Migration Setelah semua file migration selesai diedit, jalankan perintah berikut untuk mengeksekusi migration dan membuat tabel di database: php artisan migrate Jika berhasil, tabel categories, courses, dan users akan dibuat dalam database. 4. Menyesuaikan Model Setelah tabel dibuat, sesuaikan model masing-masing agar mendukung hubungan antar tabel. Model Category Buka file app/Models/Category.php dan ubah isinya menjadi: namespace App\\Models; use Illuminate\\Database\\Eloquent\\Factories\\HasFactory; use Illuminate\\Database\\Eloquent\\Model; class Category extends Model { use HasFactory; protected $fillable = ['name', 'description']; public function courses() { return $this->hasMany(Course::class); } } Model Course Buka file app/Models/Course.php dan ubah isinya menjadi: namespace App\\Models; use Illuminate\\Database\\Eloquent\\Factories\\HasFactory; use Illuminate\\Database\\Eloquent\\Model; class Course extends Model { use HasFactory; protected $fillable = ['title', 'description', 'category_id']; public function category() { return $this->belongsTo(Category::class); } } Model User Buka file app/Models/User.php dan pastikan isinya seperti berikut: namespace App\\Models; use Illuminate\\Database\\Eloquent\\Factories\\HasFactory; use Illuminate\\Foundation\\Auth\\User as Authenticatable; use Illuminate\\Notifications\\Notifiable; class User extends Authenticatable { use HasFactory, Notifiable; protected $fillable = ['name', 'email', 'password']; } Dengan langkah-langkah di atas, model dan migration untuk Category, Course, dan User sudah siap digunakan dalam proyek Laravel 12. Membuat Seeder dan Factory untuk Category, Courses, dan Users Seeder dan Factory di Laravel memungkinkan pengisian data dummy ke database dengan cepat untuk keperluan testing atau development. Berikut adalah langkah-langkah implementasi untuk Category, Courses, dan Users. 1. Membuat Factory Gunakan perintah berikut untuk membuat factory untuk masing-masing tabel: php artisan make:factory CategoryFactory --model=Category php artisan make:factory CourseFactory --model=Course php artisan make:factory UserFactory --model=User Buka file database/factories/CategoryFactory.php dan sesuaikan dengan kode berikut: namespace Database\\Factories; use App\\Models\\Category; use Illuminate\\Database\\Eloquent\\Factories\\Factory; class CategoryFactory extends Factory { protected $model = Category::class; public function definition() { return [ 'name' => $this->faker->word(), 'description' => $this->faker->sentence(), ]; } } Buka file database/factories/CourseFactory.php dan sesuaikan dengan kode berikut: namespace Database\\Factories; use App\\Models\\Course; use App\\Models\\Category; use Illuminate\\Database\\Eloquent\\Factories\\Factory; class CourseFactory extends Factory { protected $model = Course::class; public function definition() { return [ 'title' => $this->faker->sentence(), 'description' => $this->faker->paragraph(), 'category_id' => Category::factory(), ]; } } Buka file database/factories/UserFactory.php dan sesuaikan dengan kode berikut: namespace Database\\Factories; use App\\Models\\User; use Illuminate\\Database\\Eloquent\\Factories\\Factory; use Illuminate\\Support\\Str; class UserFactory extends Factory { protected $model = User::class; public function definition() { return [ 'name' => $this->faker->name(), 'email' => $this->faker->unique()->safeEmail(), 'email_verified_at' => now(), 'password' => bcrypt('password'), 'remember_token' => Str::random(10), ]; } } 2. Membuat Seeder Gunakan perintah berikut untuk membuat seeder: php artisan make:seeder CategorySeeder php artisan make:seeder CourseSeeder php artisan make:seeder UserSeeder Buka file database/seeders/CategorySeeder.php dan isi dengan kode berikut: namespace Database\\Seeders; use Illuminate\\Database\\Seeder; use App\\Models\\Category; class CategorySeeder extends Seeder { public function run() { Category::factory()->count(10)->create(); } } Buka file database/seeders/CourseSeeder.php dan isi dengan kode berikut: namespace Database\\Seeders; use Illuminate\\Database\\Seeder; use App\\Models\\Course; use App\\Models\\Category; class CourseSeeder extends Seeder { public function run() { Course::factory()->count(20)->create(); } } Buka file database/seeders/UserSeeder.php dan isi dengan kode berikut: namespace Database\\Seeders; use Illuminate\\Database\\Seeder; use App\\Models\\User; class UserSeeder extends Seeder { public function run() { User::factory()->count(5)->create(); } } 3. Memanggil Seeder di DatabaseSeeder Buka file database/seeders/DatabaseSeeder.php dan tambahkan pemanggilan seeder berikut: namespace Database\\Seeders; use Illuminate\\Database\\Seeder; class DatabaseSeeder extends Seeder { public function run() { $this->call([ UserSeeder::class, CategorySeeder::class, CourseSeeder::class, ]); } } 4. Menjalankan Seeder Jalankan perintah berikut untuk mengisi database dengan data dummy: php artisan db:seed Jika ingin mengosongkan database terlebih dahulu sebelum menjalankan seeder, gunakan perintah berikut: php artisan migrate:fresh --seed Dengan langkah-langkah ini, Seeder dan Factory telah dibuat untuk Category, Courses, dan Users, sehingga data dummy dapat dihasilkan dengan cepat untuk testing dan development. Menerapkan Service Repository Pattern untuk Categories Service Repository Pattern membantu dalam memisahkan logika bisnis dari controller, sehingga kode lebih bersih dan mudah dipelihara. Berikut adalah cara penerapannya untuk Categories di Laravel 12. 1. Membuat Repository Buat folder app/Repositories, lalu buat file CategoryRepository.php di dalamnya: namespace App\\Repositories; use App\\Models\\Category; class CategoryRepository { public function getAll() { return Category::all(); } public function findById($id) { return Category::findOrFail($id); } public function create(array $data) { return Category::create($data); } public function update($id, array $data) { $category = Category::findOrFail($id); $category->update($data); return $category; } public function delete($id) { $category = Category::findOrFail($id); return $category->delete(); } } 2. Membuat Service Buat folder app/Services, lalu buat file CategoryService.php di dalamnya: namespace App\\Services; use App\\Repositories\\CategoryRepository; class CategoryService { protected $categoryRepository; public function __construct(CategoryRepository $categoryRepository) { $this->categoryRepository = $categoryRepository; } public function getAllCategories() { return $this->categoryRepository->getAll(); } public function getCategoryById($id) { return $this->categoryRepository->findById($id); } public function createCategory($data) { return $this->categoryRepository->create($data); } public function updateCategory($id, $data) { return $this->categoryRepository->update($id, $data); } public function deleteCategory($id) { return $this->categoryRepository->delete($id); } } 3. Membuat Controller Gunakan perintah berikut untuk membuat controller: php artisan make:controller CategoryController Buka file app/Http/Controllers/CategoryController.php dan ubah isinya menjadi: namespace App\\Http\\Controllers; use App\\Services\\CategoryService; use Illuminate\\Http\\Request; class CategoryController extends Controller { protected $categoryService; public function __construct(CategoryService $categoryService) { $this->categoryService = $categoryService; } public function index() { return response()->json($this->categoryService->getAllCategories()); } public function store(Request $request) { $data = $request->validate([ 'name' => 'required|string|max:255', 'description' => 'nullable|string' ]); return response()->json($this->categoryService->createCategory($data)); } public function show($id) { return response()->json($this->categoryService->getCategoryById($id)); } public function update(Request $request, $id) { $data = $request->validate([ 'name' => 'required|string|max:255', 'description' => 'nullable|string' ]); return response()->json($this->categoryService->updateCategory($id, $data)); } public function destroy($id) { return response()->json(['deleted' => $this->categoryService->deleteCategory($id)]); } } 4. Menambahkan Route Buka file routes/api.php dan tambahkan kode berikut untuk mengakses data kategori melalui API: use App\\Http\\Controllers\\CategoryController; Route::get('/categories', [CategoryController::class, 'index']); Route::post('/categories', [CategoryController::class, 'store']); Route::get('/categories/{id}', [CategoryController::class, 'show']); Route::put('/categories/{id}', [CategoryController::class, 'update']); Route::delete('/categories/{id}', [CategoryController::class, 'destroy']); 5. Testing API Gunakan tool seperti Postman atau cURL untuk menguji API ini: Mendapatkan semua kategori GET <http://127.0.0.1:8000/api/categories>Membuat kategori baru POST <http://127.0.0.1:8000/api/categories> Content-Type: application/json { "name": "Web Development", "description": "Kategori kursus untuk pengembangan web" }Mendapatkan kategori berdasarkan ID GET <http://127.0.0.1:8000/api/categories/1>Mengupdate kategori PUT <http://127.0.0.1:8000/api/categories/1> Content-Type: application/json { "name": "Updated Web Development", "description": "Kategori kursus yang telah diperbarui" }Menghapus kategori DELETE <http://127.0.0.1:8000/api/categories/1> Dengan langkah-langkah ini, Service Repository Pattern telah diterapkan untuk tabel Categories, membuat kode lebih terstruktur dan mudah dipelihara. Menerapkan Service Repository Pattern untuk Courses Service Repository Pattern memisahkan logika bisnis dari controller, sehingga kode lebih terstruktur, mudah dipelihara, dan dapat digunakan kembali. Berikut adalah implementasi lengkap untuk Courses di Laravel 12. 1. Membuat Repository Buat folder app/Repositories, lalu buat file CourseRepository.php di dalamnya: namespace App\\Repositories; use App\\Models\\Course; class CourseRepository { public function getAll() { return Course::with('category')->get(); } public function findById($id) { return Course::with('category')->findOrFail($id); } public function create(array $data) { return Course::create($data); } public function update($id, array $data) { $course = Course::findOrFail($id); $course->update($data); return $course; } public function delete($id) { $course = Course::findOrFail($id); return $course->delete(); } } 2. Membuat Service Buat folder app/Services, lalu buat file CourseService.php di dalamnya: namespace App\\Services; use App\\Repositories\\CourseRepository; class CourseService { protected $courseRepository; public function __construct(CourseRepository $courseRepository) { $this->courseRepository = $courseRepository; } public function getAllCourses() { return $this->courseRepository->getAll(); } public function getCourseById($id) { return $this->courseRepository->findById($id); } public function createCourse($data) { return $this->courseRepository->create($data); } public function updateCourse($id, $data) { return $this->courseRepository->update($id, $data); } public function deleteCourse($id) { return $this->courseRepository->delete($id); } } 3. Membuat Controller Gunakan perintah berikut untuk membuat controller: php artisan make:controller CourseController Buka file app/Http/Controllers/CourseController.php dan ubah isinya menjadi: namespace App\\Http\\Controllers; use App\\Services\\CourseService; use Illuminate\\Http\\Request; class CourseController extends Controller { protected $courseService; public function __construct(CourseService $courseService) { $this->courseService = $courseService; } public function index() { return response()->json($this->courseService->getAllCourses()); } public function store(Request $request) { $data = $request->validate([ 'title' => 'required|string|max:255', 'description' => 'nullable|string', 'category_id' => 'required|exists:categories,id' ]); return response()->json($this->courseService->createCourse($data)); } public function show($id) { return response()->json($this->courseService->getCourseById($id)); } public function update(Request $request, $id) { $data = $request->validate([ 'title' => 'required|string|max:255', 'description' => 'nullable|string', 'category_id' => 'required|exists:categories,id' ]); return response()->json($this->courseService->updateCourse($id, $data)); } public function destroy($id) { return response()->json(['deleted' => $this->courseService->deleteCourse($id)]); } } 4. Menambahkan Route Buka file routes/api.php dan tambahkan kode berikut untuk mengakses data Courses melalui API: use App\\Http\\Controllers\\CourseController; Route::get('/courses', [CourseController::class, 'index']); Route::post('/courses', [CourseController::class, 'store']); Route::get('/courses/{id}', [CourseController::class, 'show']); Route::put('/courses/{id}', [CourseController::class, 'update']); Route::delete('/courses/{id}', [CourseController::class, 'destroy']); 5. Testing API Gunakan tool seperti Postman atau cURL untuk menguji API ini: Mendapatkan semua courses GET <http://127.0.0.1:8000/api/courses>Membuat course baru POST <http://127.0.0.1:8000/api/courses> Content-Type: application/json { "title": "Belajar Laravel", "description": "Kursus Laravel untuk pemula", "category_id": 1 }Mendapatkan course berdasarkan ID GET <http://127.0.0.1:8000/api/courses/1>Mengupdate course PUT <http://127.0.0.1:8000/api/courses/1> Content-Type: application/json { "title": "Updated Laravel Course", "description": "Kursus Laravel dengan materi lebih lengkap", "category_id": 1 }Menghapus course DELETE <http://127.0.0.1:8000/api/courses/1> Dengan langkah-langkah ini, Service Repository Pattern telah diterapkan untuk Courses, membuat kode lebih modular, terstruktur, dan mudah dipelihara. Menerapkan Authentication Sanctum API di Laravel 12 dan Membungkus Categories CRUD agar Hanya Bisa Diakses Setelah Login Laravel Sanctum memungkinkan autentikasi API yang ringan dan sederhana. Berikut adalah cara implementasi autentikasi menggunakan Sanctum dan membatasi akses ke Categories CRUD agar hanya bisa diakses oleh pengguna yang sudah login. 1. Instalasi Laravel Sanctum Jalankan perintah berikut untuk menginstal Sanctum: composer require laravel/sanctum Publikasikan konfigurasi Sanctum: php artisan vendor:publish --provider="Laravel\\Sanctum\\SanctumServiceProvider" Jalankan migrasi untuk membuat tabel personal_access_tokens: php artisan migrate Tambahkan HasApiTokens ke dalam model User di app/Models/User.php: namespace App\\Models; use Illuminate\\Database\\Eloquent\\Factories\\HasFactory; use Illuminate\\Foundation\\Auth\\User as Authenticatable; use Illuminate\\Notifications\\Notifiable; use Laravel\\Sanctum\\HasApiTokens; class User extends Authenticatable { use HasApiTokens, HasFactory, Notifiable; protected $fillable = ['name', 'email', 'password']; } Tambahkan middleware Sanctum di app/Http/Kernel.php pada bagian $middlewareGroups['api']: protected $middlewareGroups = [ 'api' => [ \\Laravel\\Sanctum\\Http\\Middleware\\EnsureFrontendRequestsAreStateful::class, 'throttle:api', \\Illuminate\\Routing\\Middleware\\SubstituteBindings::class, ], ]; 2. Membuat Controller untuk Authentication Gunakan perintah berikut untuk membuat AuthController: php artisan make:controller AuthController Buka file app/Http/Controllers/AuthController.php dan tambahkan kode berikut: namespace App\\Http\\Controllers; use App\\Models\\User; use Illuminate\\Http\\Request; use Illuminate\\Support\\Facades\\Hash; use Illuminate\\Validation\\ValidationException; class AuthController extends Controller { public function register(Request $request) { $request->validate([ 'name' => 'required|string|max:255', 'email' => 'required|string|email|unique:users', 'password' => 'required|string|min:8', ]); $user = User::create([ 'name' => $request->name, 'email' => $request->email, 'password' => Hash::make($request->password), ]); $token = $user->createToken('auth_token')->plainTextToken; return response()->json(['token' => $token], 201); } public function login(Request $request) { $request->validate([ 'email' => 'required|string|email', 'password' => 'required|string', ]); $user = User::where('email', $request->email)->first(); if (!$user || !Hash::check($request->password, $user->password)) { throw ValidationException::withMessages([ 'email' => ['The provided credentials are incorrect.'], ]); } $token = $user->createToken('auth_token')->plainTextToken; return response()->json(['token' => $token]); } public function logout(Request $request) { $request->user()->tokens()->delete(); return response()->json(['message' => 'Logged out']); } } 3. Membungkus Categories CRUD dalam Middleware Auth Buka file routes/api.php dan ubah menjadi seperti berikut: use App\\Http\\Controllers\\AuthController; use App\\Http\\Controllers\\CategoryController; use Illuminate\\Support\\Facades\\Route; // Routes untuk Authentication Route::post('/register', [AuthController::class, 'register']); Route::post('/login', [AuthController::class, 'login']); // Routes yang membutuhkan autentikasi Route::middleware('auth:sanctum')->group(function () { Route::post('/logout', [AuthController::class, 'logout']); Route::get('/categories', [CategoryController::class, 'index']); Route::post('/categories', [CategoryController::class, 'store']); Route::get('/categories/{id}', [CategoryController::class, 'show']); Route::put('/categories/{id}', [CategoryController::class, 'update']); Route::delete('/categories/{id}', [CategoryController::class, 'destroy']); }); 4. Uji Coba API Menggunakan Postman Register User Method: POSTURL: http://127.0.0.1:8000/api/registerHeaders: Content-Type: application/jsonBody (JSON): { "name": "John Doe", "email": "[email protected]", "password": "password123" }Response: { "token": "generated_token_here" } Login User Method: POSTURL: http://127.0.0.1:8000/api/loginHeaders: Content-Type: application/jsonBody (JSON): { "email": "[email protected]", "password": "password123" }Response: { "token": "generated_token_here" } Mencoba Akses CRUD Categories Tanpa Login Method: GETURL: http://127.0.0.1:8000/api/categoriesResponse: { "message": "Unauthenticated." } Akses CRUD Categories dengan Token Tambahkan Header:Authorization: Bearer generated_token_hereMendapatkan Semua CategoriesMethod: GETURL: http://127.0.0.1:8000/api/categoriesMenambahkan Category BaruMethod: POSTURL: http://127.0.0.1:8000/api/categoriesBody (JSON): { "name": "Programming", "description": "Kategori untuk kursus pemrograman" }Mengupdate CategoryMethod: PUTURL: http://127.0.0.1:8000/api/categories/1Body (JSON): { "name": "Updated Programming", "description": "Kategori pemrograman terbaru" }Menghapus CategoryMethod: DELETEURL: http://127.0.0.1:8000/api/categories/1 Logout User Method: POSTURL: http://127.0.0.1:8000/api/logoutResponse: { "message": "Logged out" } Setelah logout, jika mencoba akses Categories CRUD lagi tanpa login, API akan mengembalikan pesan "Unauthenticated." Dengan langkah-langkah ini, Sanctum API Authentication telah diterapkan, dan akses ke Categories CRUD telah diamankan sehingga hanya pengguna yang login yang bisa mengaksesnya. Kesimpulan yang Telah Dipelajari pada Artikel Ini Laravel Sanctum untuk API Authentication Laravel Sanctum digunakan untuk mengelola autentikasi berbasis token, memungkinkan pengguna untuk melakukan login, mendapatkan token akses, dan mengamankan API hanya untuk pengguna yang sudah terautentikasi.Implementasi Service Repository Pattern Dengan menerapkan Service Repository Pattern, logika bisnis dipisahkan dari controller, sehingga kode menjadi lebih modular, mudah dikelola, dan dapat digunakan kembali.Membatasi Akses API dengan Middleware Auth Middleware auth:sanctum digunakan untuk melindungi endpoint API, sehingga hanya pengguna yang telah login yang bisa mengakses CRUD Categories, sementara pengguna yang tidak terautentikasi akan mendapatkan pesan "Unauthenticated."Pengujian API dengan Postman Setiap endpoint diuji menggunakan Postman, termasuk:Register dan login untuk mendapatkan token.Menggunakan token untuk mengakses Categories CRUD.Logout dan mencoba kembali mengakses API tanpa login untuk memastikan proteksi berjalan dengan baik.Pengelolaan User Authentication dan LogoutSaat pengguna login, Laravel Sanctum menghasilkan personal access token yang digunakan untuk mengakses API.Logout akan menghapus semua token aktif pengguna, sehingga akses API menjadi tidak valid hingga pengguna login kembali. Dengan penerapan Laravel Sanctum dan Service Repository Pattern, API menjadi lebih aman, terstruktur, dan mudah dipelihara untuk proyek-proyek berbasis backend Laravel. Penutup dan Saran Membangun API yang aman dan terstruktur dengan Laravel tidak hanya membutuhkan pemahaman tentang framework itu sendiri, tetapi juga penerapan praktik terbaik seperti Service Repository Pattern dan Sanctum Authentication. Dengan menerapkan metode ini, kita bisa membuat aplikasi yang lebih scalable, mudah dipelihara, dan siap untuk produksi. Namun, belajar sendiri terkadang bisa membingungkan dan memakan waktu. Untuk itu, bagi para web developer yang ingin meningkatkan skill mereka secara lebih efektif, belajar bersama mentor expert di BuildWithAngga adalah pilihan yang tepat. Di BuildWithAngga, Anda bisa mendapatkan berbagai benefit eksklusif, seperti: ✅ Akses Materi Seumur Hidup – Belajar kapan saja tanpa batasan waktu. ✅ Sertifikat Kelulusan – Sebagai bukti keahlian untuk meningkatkan kredibilitas Anda. ✅ Portfolio Berkualitas – Membangun proyek nyata yang bisa menjadi modal utama untuk mendapatkan pekerjaan impian. Jangan ragu untuk terus mengembangkan skill Anda bersama mentor terbaik! 🚀

Kelas Tutorial Bikin User Authentication dengan Golang Gin dan JWT Pada Projek Website Sewa Mobil di BuildWithAngga

Tutorial Bikin User Authentication dengan Golang Gin dan JWT Pada Projek Website Sewa Mobil

Fitur authentication (auth) sangat penting dalam sebuah website, terutama jika platform tersebut melibatkan data pengguna. Dengan auth, pengguna dapat melakukan registrasi dan login ke akun mereka untuk mengelola informasi penting, seperti profil, transaksi, atau pengaturan lainnya. Tanpa sistem auth yang baik, data pengguna bisa rentan terhadap akses tidak sah, yang berisiko menyebabkan kebocoran informasi atau penyalahgunaan akun. Sistem auth biasanya mencakup beberapa komponen utama, seperti login, registrasi, otorisasi berdasarkan peran pengguna, serta perlindungan terhadap serangan seperti brute force dan session hijacking. Oleh karena itu, implementasi auth yang aman sangat diperlukan dalam pengembangan website profesional. Belajar Golang, Gin, dan JWT untuk Fitur Auth pada Website Toko Sewa Mobil Dalam artikel ini, kita akan membahas bagaimana membangun fitur auth menggunakan Golang, Gin, dan JWT untuk sebuah website toko sewa mobil. Golang adalah bahasa yang cepat dan efisien, sementaara Gin adalah framework yang mempermudah pengembangan web API di Golang. Sedangkan JWT (JSON Web Token) digunakan sebagai mekanisme untuk mengelola sesi login pengguna dengan aman. Dengan kombinasi teknologi ini, kita bisa membuat sistem auth yang memungkinkan pengguna untuk mendaftar dan masuk ke akun meareka, sehingga mereka dapat menyewa mobil, melihat riwayat pemesanan, atau mengelola informasi lainnya dengan aman. Fitur ini juga membantu memastikan bahwa hanya pengguna yang sudah terautentikasi yang dapaat mengakses data sensitif. Di artikel selanjutnya, kita akan membahas bagaimana mengimplementasiakan fitur auth ini dengan kode secara bertahap. Membuat Proyek Golang Terbaru dan Menginstal Dependensi Untuk memulai proyek Golang terbaru, pastikan Golang telah diinstal di sistem. Gunakan versi terbaru agar mendapatkan fitur terbaru dan perbaikan keamanan. Buka terminal dan buat folder proyek: mkdir rental-car-api cd rental-car-api go mod init github.com/yourusername/rental-car-api Perintah ini menginisialisasi proyek dengan go.mod, yang mengelola dependensi proyek. Setelah itu, instal beberapa library yang akan digunakan: go get -u github.com/gin-gonic/gin go get -u gorm.io/gorm go get -u gorm.io/driver/mysql go get -u github.com/joho/godotenv go get -u github.com/golang-jwt/jwt/v5 go get -u github.com/google/uuid Gin digunakan untuk membangun web API, GORM untuk ORM, dotenv untuk membaca konfigurasi dari file .env, JWT untuk autentikasi, dan UUID untuk membuat ID unik. Buat file .env di root proyek untuk menyimpan konfigurasi database: DB_USER=root DB_PASSWORD=password DB_HOST=127.0.0.1 DB_PORT=3306 DB_NAME=rental_car JWT_SECRET=your_secret_key File ini digunakan untuk menyimpan kredensial sensitif agar tidak hardcoded dalam kode sumber. Konfigurasi Database dan Auto Migrate dengan GORM Buat folder database dan buat file database/connection.go: package database import ( "fmt" "log" "os" "gorm.io/driver/mysql" "gorm.io/gorm" "github.com/joho/godotenv" "github.com/yourusername/rental-car-api/models" ) var DB *gorm.DB func Connect() { err := godotenv.Load() if err != nil { log.Fatal("Error loading .env file") } dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", os.Getenv("DB_USER"), os.Getenv("DB_PASSWORD"), os.Getenv("DB_HOST"), os.Getenv("DB_PORT"), os.Getenv("DB_NAME"), ) DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{}) if err != nil { log.Fatal("Failed to connect to database:", err) } DB.AutoMigrate(&models.User{}, &models.Car{}) } Kode ini membaca konfigurasi database dari .env, membuat koneksi ke MySQL, dan melakukan auto migrate untuk tabel users dan cars. Membuat Model User Buat folder models, lalu buat file models/user.go: package models import ( "github.com/google/uuid" "gorm.io/gorm" ) type User struct { ID uuid.UUID `gorm:"type:char(36);primary_key" json:"id"` Name string `gorm:"not null" json:"name"` Email string `gorm:"unique;not null" json:"email"` Password string `gorm:"not null" json:"-"` } func (u *User) BeforeCreate(tx *gorm.DB) (err error) { u.ID = uuid.New() return } Model ini menggunakan UUID sebagai primary key agar lebih aman dan unik dibandingkan dengan integer. Fungsi BeforeCreate memastikan bahwa setiap pengguna memiliki UUID baru sebelum disimpan ke database. Membuat Model Car Buat file models/car.go: package models import ( "github.com/google/uuid" "gorm.io/gorm" ) type Car struct { ID uuid.UUID `gorm:"type:char(36);primary_key" json:"id"` Brand string `gorm:"not null" json:"brand"` Model string `gorm:"not null" json:"model"` Year int `gorm:"not null" json:"year"` Price float64 `gorm:"not null" json:"price"` Status string `gorm:"default:'available'" json:"status"` } func (c *Car) BeforeCreate(tx *gorm.DB) (err error) { c.ID = uuid.New() return } Sama seperti model User, model Car menggunakan UUID untuk ID. Status mobil secara default akan diatur ke "available". Menghubungkan Database ke main.go Buka main.go dan tambahkan kode berikut: package main import ( "github.com/gin-gonic/gin" "github.com/yourusername/rental-car-api/database" ) func main() { database.Connect() r := gin.Default() r.Run(":8080") } Kode ini memastikan bahwa koneksi ke database sudah terjalin sebelum server dijalankan pada port 8080. Menjalankan Proyek Jalankan proyek dengan perintah berikut: go run main.go Jika berhasil, database akan terkoneksi dan tabel users serta cars akan dibuat secara otomatis. Untuk mengecek apakah tabel berhasil dibuat, jalankan perintah berikut di MySQL: SHOW TABLES; DESCRIBE users; DESCRIBE cars; Dengan langkah ini, sistem database sudah siap untuk digunakan dalam proyek website toko sewa mobil. Struktur Folder untuk Proyek Website Sewa Mobil Online (Golang + Gin + GORM) Agar proyek website sewa mobil online lebih terstruktur dan mudah dikelola, folder dan file harus diorganisir dengan baik. Berikut adalah struktur yang direkomendasikan beserta penjelasan detailnya: rental-car-api/ │── .env │── .gitignore │── go.mod │── go.sum │── main.go │── database/ │ ├── connection.go │── models/ │ ├── user.go │ ├── car.go │── controllers/ │ ├── authController.go │ ├── carController.go │── routes/ │ ├── authRoutes.go │ ├── carRoutes.go │── middlewares/ │ ├── authMiddleware.go │── utils/ │ ├── jwtHelper.go │ ├── hashHelper.go │── config/ │ ├── config.go │── storage/ │ ├── uploads/ Penjelasan Detail Struktur Folder dan Fungsinya 1. Root Folder (rental-car-api/) Folder utama proyek yang berisi file konfigurasi utama dan file entry point (main.go). File di dalam root folder: .env → File untuk menyimpan variabel lingkungan (environment variables) seperti konfigurasi database, secret key JWT, dan lainnya..gitignore → Menentukan file atau folder yang tidak perlu di-track oleh Git, seperti node_modules, uploads/, atau file cache.go.mod → File yang berisi daftar dependensi proyek Golang yang dibuat dengan go mod init.go.sum → Menyimpan versi spesifik dari setiap dependensi yang diunduh.main.go → Entry point dari aplikasi yang menjalankan server Gin dan menghubungkan berbagai komponen proyek. 2. Folder database/ (Koneksi dan Migrasi Database) Folder ini berisi file untuk mengatur koneksi database dan melakukan migrasi otomatis. File di dalam folder database/ connection.go → Berisi fungsi untuk menghubungkan Golang dengan database (MySQL, PostgreSQL, atau SQLite) menggunakan GORM. Contoh kode di database/connection.go: package database import ( "fmt" "log" "os" "gorm.io/driver/mysql" "gorm.io/gorm" "github.com/joho/godotenv" "github.com/yourusername/rental-car-api/models" ) var DB *gorm.DB func Connect() { err := godotenv.Load() if err != nil { log.Fatal("Error loading .env file") } dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", os.Getenv("DB_USER"), os.Getenv("DB_PASSWORD"), os.Getenv("DB_HOST"), os.Getenv("DB_PORT"), os.Getenv("DB_NAME"), ) DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{}) if err != nil { log.Fatal("Failed to connect to database:", err) } DB.AutoMigrate(&models.User{}, &models.Car{}) } 3. Folder models/ (Definisi Struktur Data atau Tabel Database) Folder ini berisi definisi model yang merepresentasikan tabel dalam database. File di dalam folder models/ user.go → Model pengguna (users).car.go → Model mobil (cars). Contoh kode di models/user.go: package models import ( "github.com/google/uuid" "gorm.io/gorm" ) type User struct { ID uuid.UUID `gorm:"type:char(36);primary_key" json:"id"` Name string `gorm:"not null" json:"name"` Email string `gorm:"unique;not null" json:"email"` Password string `gorm:"not null" json:"-"` } func (u *User) BeforeCreate(tx *gorm.DB) (err error) { u.ID = uuid.New() return } 4. Folder controllers/ (Logika Bisnis dan Fungsi API) Folder ini berisi handler yang menangani permintaan API dan mengembalikan respons ke client. File di dalam folder controllers/ authController.go → Mengelola registrasi, login, dan pengelolaan sesi.carController.go → Mengelola data mobil, seperti menampilkan daftar mobil atau mengubah status mobil. Contoh kode di controllers/authController.go: package controllers import ( "net/http" "github.com/gin-gonic/gin" "github.com/yourusername/rental-car-api/database" "github.com/yourusername/rental-car-api/models" ) func GetUsers(c *gin.Context) { var users []models.User database.DB.Find(&users) c.JSON(http.StatusOK, users) } 5. Folder routes/ (Pengaturan Rute API) Folder ini berisi daftar endpoint yang digunakan dalam aplikasi. File di dalam folder routes/ authRoutes.go → Rute untuk login, registrasi, dan autentikasi.carRoutes.go → Rute untuk pengelolaan mobil. Contoh kode di routes/authRoutes.go: package routes import ( "github.com/gin-gonic/gin" "github.com/yourusername/rental-car-api/controllers" ) func AuthRoutes(r *gin.Engine) { auth := r.Group("/auth") { auth.GET("/users", controllers.GetUsers) } } 6. Folder middlewares/ (Middleware untuk Proteksi API) Folder ini berisi middleware yang digunakan untuk validasi dan keamanan API. File di dalam folder middlewares/ authMiddleware.go → Middleware untuk memvalidasi JWT token. Contoh kode di middlewares/authMiddleware.go: package middlewares import ( "net/http" "strings" "github.com/gin-gonic/gin" ) func AuthMiddleware() gin.HandlerFunc { return func(c *gin.Context) { token := c.GetHeader("Authorization") if token == "" || !strings.HasPrefix(token, "Bearer ") { c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"}) c.Abort() return } c.Next() } } 7. Folder utils/ (Helper Function atau Utility) Folder ini berisi fungsi pembantu yang sering digunakan dalam proyek. File di dalam folder utils/ jwtHelper.go → Fungsi untuk membuat dan memverifikasi token JWT.hashHelper.go → Fungsi untuk melakukan hash dan verifikasi password. 8. Folder config/ (Konfigurasi Tambahan) Folder ini digunakan untuk menyimpan konfigurasi tambahan seperti pengaturan aplikasi. File di dalam folder config/ config.go → Menyediakan konfigurasi global untuk proyek. 9. Folder storage/ (Penyimpanan File Uploads) Folder ini digunakan untuk menyimpan file gambar atau dokumen yang diunggah oleh pengguna. Folder di dalam storage/ uploads/ → Folder tempat penyimpanan file yang diunggah. Dengan struktur folder ini, proyek website sewa mobil online akan lebih terorganisir dan mudah dipahami, terutama jika dikembangkan dalam tim. Membuat CRUD Data Users pada Controller, Routes, dan JWT Utils CRUD (Create, Read, Update, Delete) adalah dasar dalam pengelolaan data pengguna. Implementasi ini mencakup registrasi (sign up), login (sign in), membaca daftar pengguna, memperbarui data pengguna, dan menghapus pengguna. Membuat Controller untuk CRUD Users Buat file controllers/userController.go yang menangani operasi CRUD untuk tabel users. package controllers import ( "net/http" "github.com/gin-gonic/gin" "github.com/yourusername/rental-car-api/database" "github.com/yourusername/rental-car-api/models" "github.com/yourusername/rental-car-api/utils" "github.com/yourusername/rental-car-api/middlewares" ) func RegisterUser(c *gin.Context) { var user models.User if err := c.ShouldBindJSON(&user); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } hashedPassword, err := utils.HashPassword(user.Password) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to hash password"}) return } user.Password = hashedPassword if err := database.DB.Create(&user).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create user"}) return } c.JSON(http.StatusCreated, gin.H{"message": "User registered successfully"}) } func LoginUser(c *gin.Context) { var input models.User if err := c.ShouldBindJSON(&input); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } var user models.User if err := database.DB.Where("email = ?", input.Email).First(&user).Error; err != nil { c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid email or password"}) return } if !utils.CheckPasswordHash(input.Password, user.Password) { c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid email or password"}) return } token, err := utils.GenerateJWT(user.ID) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to generate token"}) return } c.JSON(http.StatusOK, gin.H{"token": token}) } func GetUsers(c *gin.Context) { var users []models.User database.DB.Find(&users) c.JSON(http.StatusOK, users) } func UpdateUser(c *gin.Context) { userID := c.Param("id") var user models.User if err := database.DB.First(&user, userID).Error; err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "User not found"}) return } if err := c.ShouldBindJSON(&user); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } database.DB.Save(&user) c.JSON(http.StatusOK, gin.H{"message": "User updated successfully", "user": user}) } func DeleteUser(c *gin.Context) { userID := c.Param("id") if err := database.DB.Delete(&models.User{}, userID).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to delete user"}) return } c.JSON(http.StatusOK, gin.H{"message": "User deleted successfully"}) } Membuat Routing untuk User CRUD Buat file routes/userRoutes.go yang akan mengatur endpoint untuk fitur CRUD pengguna. package routes import ( "github.com/gin-gonic/gin" "github.com/yourusername/rental-car-api/controllers" "github.com/yourusername/rental-car-api/middlewares" ) func UserRoutes(r *gin.Engine) { users := r.Group("/users") { users.POST("/register", controllers.RegisterUser) users.POST("/login", controllers.LoginUser) users.GET("/", middlewares.AuthMiddleware(), controllers.GetUsers) users.PUT("/:id", middlewares.AuthMiddleware(), controllers.UpdateUser) users.DELETE("/:id", middlewares.AuthMiddleware(), controllers.DeleteUser) } } Routing ini memastikan bahwa mendapatkan daftar pengguna, mengupdate pengguna, dan menghapus pengguna hanya bisa dilakukan oleh pengguna yang telah login (menggunakan middleware AuthMiddleware). Membuat JWT Utils untuk Autentikasi Buat file utils/jwtHelper.go yang berisi fungsi untuk membuat dan memverifikasi token JWT. package utils import ( "time" "os" "github.com/golang-jwt/jwt/v5" "github.com/google/uuid" ) var jwtSecret = []byte(os.Getenv("JWT_SECRET")) func GenerateJWT(userID uuid.UUID) (string, error) { claims := jwt.MapClaims{ "user_id": userID.String(), "exp": time.Now().Add(time.Hour * 24).Unix(), } token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) return token.SignedString(jwtSecret) } func VerifyJWT(tokenString string) (*jwt.Token, error) { return jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { return jwtSecret, nil }) } Membuat Utils untuk Hashing Password pada Proses Sign Up dan Sign In Agar password aman, sebaiknya disimpan dalam bentuk hashed password menggunakan bcrypt. Buat file utils/hashHelper.go untuk menangani hashing password. package utils import ( "golang.org/x/crypto/bcrypt" ) // HashPassword melakukan hashing pada password sebelum disimpan ke database func HashPassword(password string) (string, error) { bytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) return string(bytes), err } // CheckPasswordHash memeriksa apakah password yang diberikan cocok dengan hash yang tersimpan di database func CheckPasswordHash(password, hash string) bool { err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) return err == nil } Ketika pengguna melakukan registrasi, password akan di-hash sebelum disimpan ke database menggunakan fungsi HashPassword. Saat pengguna login, password yang dimasukkan akan dibandingkan dengan yang ada di database menggunakan CheckPasswordHash. Menghubungkan Semua ke main.go Terakhir, pastikan semua komponen sudah terhubung di main.go untuk menjalankan server dengan fitur CRUD Users. package main import ( "github.com/gin-gonic/gin" "github.com/yourusername/rental-car-api/database" "github.com/yourusername/rental-car-api/routes" "github.com/joho/godotenv" "log" ) func main() { err := godotenv.Load() if err != nil { log.Fatal("Error loading .env file") } database.Connect() r := gin.Default() routes.UserRoutes(r) r.Run(":8080") } Server akan berjalan di port 8080, dan API CRUD Users bisa digunakan. Menjalankan Proyek dan Menguji API Jalankan server dengan perintah: go run main.go Gunakan Postman atau cURL untuk menguji API: Registrasi User → POST <http://localhost:8080/users/register>Login User → POST <http://localhost:8080/users/login>Get All Users (Protected) → GET <http://localhost:8080/users/>Update User (Protected) → PUT <http://localhost:8080/users/:id>Delete User (Protected) → DELETE <http://localhost:8080/users/:id> Dengan implementasi ini, CRUD pengguna dalam proyek website sewa mobil online telah berhasil dibuat dengan Golang, Gin, GORM, dan JWT. Tata Cara Uji Coba Endpoint APIs Menggunakan Postman Untuk memastikan API bekerja dengan benar, Postman dapat digunakan untuk melakukan uji coba. Berikut adalah cara melakukan pengujian pada endpoint API yang telah dibuat dengan Golang, Gin, GORM, dan JWT. Buka Postman dan buat request baru untuk setiap endpoint yang akan diuji. 1. Uji Coba Registrasi User (Sign Up) Pilih metode POST, lalu masukkan URL: <http://localhost:8080/users/register> Pada tab Body, pilih raw dan JSON, lalu masukkan data berikut: { "name": "John Doe", "email": "[email protected]", "password": "password123" } Klik Send. Jika berhasil, respons yang diterima: { "message": "User registered successfully" } 2. Uji Coba Login User (Sign In) dan Mendapatkan JWT Token Pilih metode POST, lalu masukkan URL: <http://localhost:8080/users/login> Pada tab Body, pilih raw dan JSON, lalu masukkan data berikut: { "email": "[email protected]", "password": "password123" } Klik Send. Jika berhasil, respons yang diterima akan berisi token JWT seperti ini: { "token": "eyJhbGciOiJIUzI1NiIsIn..." } Salin token yang diberikan karena akan digunakan untuk mengakses endpoint yang memerlukan autentikasi. 3. Uji Coba Mendapatkan Daftar Pengguna (Protected Endpoint) Pilih metode GET, lalu masukkan URL: <http://localhost:8080/users/> Buka tab Headers dan tambahkan Authorization dengan nilai: Bearer <JWT_TOKEN_YANG_TELAH_DIPEROLEH> Klik Send. Jika token valid, respons yang diterima akan berupa daftar pengguna: [ { "id": "3f36e750-4535-4a9f-9049-89a19f08d0f2", "name": "John Doe", "email": "[email protected]" } ] Jika token tidak valid atau tidak disertakan, respons yang diterima adalah: { "error": "Unauthorized" } 4. Uji Coba Update Data User (Protected Endpoint) Pilih metode PUT, lalu masukkan URL dengan ID user yang ingin diperbarui: <http://localhost:8080/users/3f36e750-4535-4a9f-9049-89a19f08d0f2> Buka tab Headers dan tambahkan Authorization seperti sebelumnya. Pada tab Body, pilih raw dan JSON, lalu masukkan data berikut: { "name": "John Updated", "email": "[email protected]" } Klik Send. Jika berhasil, respons yang diterima: { "message": "User updated successfully", "user": { "id": "3f36e750-4535-4a9f-9049-89a19f08d0f2", "name": "John Updated", "email": "[email protected]" } } 5. Uji Coba Hapus User (Protected Endpoint) Pilih metode DELETE, lalu masukkan URL dengan ID user yang ingin dihapus: <http://localhost:8080/users/3f36e750-4535-4a9f-9049-89a19f08d0f2> Buka tab Headers dan tambahkan Authorization seperti sebelumnya. Klik Send. Jika berhasil, respons yang diterima: { "message": "User deleted successfully" } Jika user dengan ID tersebut tidak ditemukan, respons yang diterima adalah: { "error": "User not found" } Dengan langkah-langkah ini, API telah diuji dengan Postman untuk memastikan bahwa setiap endpoint bekerja dengan benar, termasuk autentikasi menggunakan JWT. Penjelasan Soft Delete Soft delete adalah teknik menghapus data dengan menandai bahwa data telah dihapus tanpa benar-benar menghapusnya dari database. Alih-alih menghapus baris data secara permanen, sistem akan menambahkan kolom seperti deleted_at, dan jika kolom ini memiliki nilai, maka data dianggap telah dihapus. Analogi Soft Delete Bayangkan sebuah keranjang sampah di komputer. Saat file dihapus, file tidak langsung hilang dari sistem, tetapi dipindahkan ke keranjang sampah. File tersebut tetap ada dan bisa dikembalikan kapan saja. Namun, ketika pengguna mengosongkan keranjang sampah, barulah file benar-benar dihapus dari sistem. Implementasi Soft Delete Menggunakan GORM Soft delete di GORM dapat dilakukan dengan menambahkan kolom gorm.DeletedAt. Ini memungkinkan data tetap ada di database tetapi tidak akan muncul dalam query biasa kecuali diminta secara eksplisit. Buat model User dengan fitur soft delete di models/user.go: package models import ( "github.com/google/uuid" "gorm.io/gorm" ) type User struct { ID uuid.UUID `gorm:"type:char(36);primary_key" json:"id"` Name string `gorm:"not null" json:"name"` Email string `gorm:"unique;not null" json:"email"` Password string `gorm:"not null" json:"-"` DeletedAt gorm.DeletedAt `gorm:"index" json:"-"` } func (u *User) BeforeCreate(tx *gorm.DB) (err error) { u.ID = uuid.New() return } Kolom DeletedAt akan otomatis digunakan oleh GORM untuk menandai data yang dihapus. Menghapus Data dengan Soft Delete Buat fungsi DeleteUser di controllers/userController.go: func DeleteUser(c *gin.Context) { userID := c.Param("id") if err := database.DB.Where("id = ?", userID).Delete(&models.User{}).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to delete user"}) return } c.JSON(http.StatusOK, gin.H{"message": "User deleted successfully"}) } Saat user dihapus menggunakan Delete(), GORM tidak akan menghapusnya dari database, tetapi hanya akan mengisi kolom DeletedAt dengan timestamp penghapusan. Mendapatkan Data yang Tidak Dihapus Secara default, GORM akan otomatis menyaring data yang memiliki nilai DeletedAt. Jika ingin mendapatkan daftar pengguna aktif saja, gunakan query berikut: func GetUsers(c *gin.Context) { var users []models.User database.DB.Where("deleted_at IS NULL").Find(&users) c.JSON(http.StatusOK, users) } Mendapatkan Data yang Sudah Dihapus Untuk mengambil data yang sudah dihapus, gunakan query dengan Unscoped(): func GetDeletedUsers(c *gin.Context) { var users []models.User database.DB.Unscoped().Where("deleted_at IS NOT NULL").Find(&users) c.JSON(http.StatusOK, users) } Mengembalikan Data yang Terhapus (Restore) Jika pengguna ingin mengembalikan data yang telah dihapus, cukup set DeletedAt menjadi NULL: func RestoreUser(c *gin.Context) { userID := c.Param("id") database.DB.Unscoped().Model(&models.User{}).Where("id = ?", userID).Update("deleted_at", nil) c.JSON(http.StatusOK, gin.H{"message": "User restored successfully"}) } Dengan menggunakan soft delete, data tetap dapat dipulihkan kapan saja dan tidak benar-benar hilang dari database. Kesimpulan yang Telah Dipelajari Soft Delete sebagai Solusi Aman Soft delete memungkinkan data tetap tersimpan di database dengan hanya menandai sebagai "dihapus", bukan menghapusnya secara permanen. Konsep ini mirip dengan keranjang sampah di komputer, sehingga data masih bisa dipulihkan jika dibutuhkan.Dukungan GORM untuk Soft Delete GORM menyediakan fitur bawaan gorm.DeletedAt, yang secara otomatis menyaring data yang telah dihapus dari query normal. Jika ingin melihat atau mengembalikan data yang sudah dihapus, dapat menggunakan Unscoped().Keamanan Autentikasi dengan JWT JWT (JSON Web Token) digunakan untuk memastikan bahwa hanya pengguna yang telah login yang bisa mengakses data sensitif. Ini adalah metode autentikasi yang efisien dan aman dalam komunikasi antara frontend dan backend dalam aplikasi berbasis API.Pentingnya Hashing Password dengan bcrypt Password harus disimpan dalam bentuk hash untuk meningkatkan keamanan sistem. Dengan menggunakan bcrypt, password pengguna tidak tersimpan dalam bentuk teks biasa, sehingga lebih sulit dicuri atau dibobol oleh pihak yang tidak berwenang.Postman sebagai Alat Uji API yang Efektif Postman mempermudah pengujian endpoint API tanpa perlu membangun frontend terlebih dahulu. Dengan fitur seperti menyimpan token JWT dan otomatisasi request, Postman sangat membantu dalam proses pengembangan dan debugging API. Saran untuk Programmer yang Ingin Belajar Lebih Dalam Belajar dengan mentor expert di BuildWithAngga adalah pilihan terbaik bagi programmer yang ingin mempercepat pemahaman dalam membangun proyek nyata.Akses kelas selamanya memungkinkan programmer belajar dengan fleksibel tanpa batas waktu.Membangun portofolio kerja berkualitas agar lebih siap bersaing dalam dunia industri teknologi.Kesempatan magang online yang dibayar memberikan pengalaman langsung dalam proyek nyata dan meningkatkan peluang mendapatkan pekerjaan.Beragam benefit tambahan seperti networking dengan profesional, dukungan komunitas, dan pembelajaran berbasis studi kasus membuat proses belajar lebih efektif dan aplikatif.

Kelas Begini Bedanya Karir Programmer dan Software Engineer di BuildWithAngga

Begini Bedanya Karir Programmer dan Software Engineer

Di era digital saat ini, hampir semua perusahaan membutuhkan website dan aplikasi untuk menjalankan bisnis mereka. Dari perusahaan rintisan hingga korporasi besar, kebutuhan akan teknologi semakin meningkat. Inilah yang membuat karir di bidang teknologi, terutama sebagai programmer dan software engineer, menjadi pilihan yang sangat menjanjikan. Namun, banyak pemula yang masih bingung membedakan kedua profesi ini. Meskipun keduanya bekerja dalam dunia pengembangan perangkat lunak, ada perbedaan mendasar dalam cakupan pekerjaan, pendekatan kerja, dan tanggung jawab yang mereka emban. Seorang programmer lebih fokus pada proses coding, menulis dan mengimplementasikan kode agar aplikasi atau sistem berjalan sesuai kebutuhan. Mereka bertanggung jawab mengubah desain atau rencana teknis menjadi kode yang dapat dieksekusi oleh komputer. Di sisi lain, software engineer memiliki peran yang lebih luas. Mereka tidak hanya menulis kode, tetapi juga merancang dan mengembangkan sistem perangkat lunak secara keseluruhan. Seorang software engineer mempertimbangkan bagaimana sistem dibangun agar efisien, mudah dipelihara, dan bisa berkembang sesuai kebutuhan bisnis. Dengan tingginya permintaan akan produk digital, baik programmer maupun software engineer memiliki prospek karir yang cerah. Pemula yang ingin terjun ke dunia teknologi bisa memilih jalur yang sesuai dengan minat dan kemampuan mereka, apakah ingin lebih fokus pada coding atau berkontribusi dalam arsitektur sistem yang lebih kompleks. Apa Itu Programmer? Programmer adalah seseorang yang bertanggung jawab menulis, menguji, dan memperbaiki kode dalam proses pengembangan perangkat lunak. Mereka bekerja dengan berbagai bahasa pemrograman untuk membangun fitur dan memastikan sistem berjalan sesuai kebutuhan. Peran programmer sangat penting dalam mengubah konsep atau desain aplikasi menjadi produk yang bisa digunakan oleh pengguna. Peran Programmer dalam Alur Software Development Dalam proses pengembangan perangkat lunak, programmer biasanya terlibat dalam beberapa tahap, di antaranya: Menerima dan Memahami Spesifikasi Programmer bekerja berdasarkan spesifikasi yang diberikan oleh tim pengembang, seperti software engineer, product manager, atau UI/UX designer. Mereka harus memahami kebutuhan proyek sebelum mulai menulis kode.Menulis dan Mengembangkan Kode Setelah memahami spesifikasi, programmer mulai menulis kode sesuai dengan fungsionalitas yang dibutuhkan. Mereka memastikan bahwa kode yang dibuat efisien, mudah dibaca, dan sesuai dengan standar pengembangan perangkat lunak.Melakukan Pengujian dan Debugging Programmer bertanggung jawab memastikan bahwa kode yang mereka buat berjalan dengan baik. Mereka melakukan debugging jika ada kesalahan atau bug yang menyebabkan sistem tidak berfungsi sebagaimana mestinya.Berkoordinasi dengan Tim Lain Programmer bekerja sama dengan tim software engineer, designer, dan tester untuk memastikan bahwa perangkat lunak dikembangkan sesuai rencana. Komunikasi yang baik sangat penting agar setiap perubahan atau perbaikan bisa diterapkan dengan efektif.Melakukan Pemeliharaan dan Pembaruan Setelah perangkat lunak diluncurkan, programmer masih berperan dalam melakukan pembaruan atau perbaikan fitur jika dibutuhkan. Mereka memastikan bahwa sistem tetap berjalan optimal dan bisa diperbarui sesuai dengan perkembangan teknologi. Tools yang Digunakan Programmer Untuk mendukung pekerjaannya, programmer menggunakan berbagai tools, antara lain: Text Editor atau IDE (Integrated Development Environment): Digunakan untuk menulis dan mengelola kode, seperti Visual Studio Code, JetBrains, atau Sublime Text.Version Control System: Git dan platform seperti GitHub atau GitLab membantu mengelola perubahan kode dalam proyek.Debugger: Alat yang digunakan untuk menemukan dan memperbaiki kesalahan dalam kode.Database Management System: Programmer sering berinteraksi dengan database menggunakan tools seperti MySQL, PostgreSQL, atau MongoDB.Collaboration Tools: Untuk komunikasi dengan tim, programmer menggunakan platform seperti Slack, Trello, atau Jira. Cara Kerja Programmer Seorang programmer bekerja secara sistematis dalam pengembangan perangkat lunak. Biasanya, mereka mengikuti metode kerja seperti Agile atau Scrum, yang membagi proyek ke dalam tugas-tugas kecil yang dapat dikerjakan secara bertahap. Dalam kesehariannya, programmer memulai dengan membaca dokumentasi proyek, mengembangkan atau memperbaiki kode, lalu menguji hasilnya sebelum dikirim ke tim lain untuk ditinjau. Mereka juga mengikuti sesi meeting atau code review untuk memastikan kualitas kode tetap terjaga. Secara keseluruhan, programmer adalah bagian penting dalam proses pengembangan perangkat lunak. Mereka bertanggung jawab mengimplementasikan ide menjadi produk nyata yang bisa digunakan oleh pengguna. Apa Itu Software Engineer? Software engineer adalah seseorang yang merancang, mengembangkan, dan mengelola sistem perangkat lunak secara keseluruhan. Mereka tidak hanya menulis kode, tetapi juga memastikan bahwa sistem yang dibuat dapat berjalan dengan efisien, aman, dan mudah dipelihara. Seorang software engineer menerapkan prinsip-prinsip rekayasa perangkat lunak untuk membangun solusi teknologi yang skalabel dan sesuai dengan kebutuhan bisnis. Peran Software Engineer dalam Alur Software Development Dalam proses pengembangan perangkat lunak, software engineer berperan dalam beberapa tahap utama, antara lain: Analisis Kebutuhan dan Perencanaan Software engineer bekerja sama dengan tim bisnis, product manager, dan designer untuk memahami kebutuhan pengguna serta merancang solusi yang tepat. Mereka bertanggung jawab menentukan teknologi yang digunakan dan bagaimana sistem akan dikembangkan.Merancang Arsitektur Sistem Sebelum pengembangan dimulai, software engineer membuat rancangan sistem yang mencakup struktur database, API, serta bagaimana berbagai komponen aplikasi akan berinteraksi satu sama lain.Mengembangkan Perangkat Lunak Software engineer terlibat langsung dalam proses pengembangan dengan menulis kode atau membimbing tim programmer dalam implementasi solusi. Mereka memastikan bahwa kode yang dibuat mengikuti standar yang telah ditetapkan.Melakukan Pengujian dan Optimasi Setelah pengembangan, software engineer melakukan pengujian untuk memastikan sistem berjalan dengan baik. Mereka juga mengoptimalkan performa sistem agar lebih cepat, efisien, dan dapat menangani lebih banyak pengguna.Deployment dan Pemeliharaan Software engineer bertanggung jawab dalam proses deployment atau peluncuran aplikasi ke lingkungan produksi. Setelah diluncurkan, mereka tetap mengawasi sistem, melakukan pembaruan, serta menangani perbaikan jika terjadi masalah atau bug. Tools yang Digunakan Software Engineer Software engineer menggunakan berbagai tools untuk membantu pekerjaan mereka, seperti: IDE dan Text Editor: Visual Studio Code, JetBrains, atau lainnya untuk menulis dan mengelola kode.Version Control System: Git dan platform seperti GitHub atau GitLab untuk mengelola perubahan kode.Cloud Computing: AWS, Google Cloud, atau Azure untuk menyimpan dan menjalankan aplikasi di lingkungan cloud.Database Management System: MySQL, PostgreSQL, atau MongoDB untuk mengelola data aplikasi.Containerization dan Orchestration: Docker dan Kubernetes untuk menjalankan aplikasi dalam lingkungan yang lebih fleksibel.Monitoring Tools: Prometheus, Grafana, atau New Relic untuk memantau performa sistem dan mendeteksi potensi masalah lebih awal. Cara Kerja Software Engineer Software engineer bekerja dengan pendekatan yang lebih sistematis dan strategis dalam pengembangan perangkat lunak. Mereka biasanya mengikuti metodologi pengembangan seperti Agile atau DevOps untuk memastikan bahwa proses development berjalan lebih cepat dan efisien. Dalam kesehariannya, software engineer tidak hanya menulis kode, tetapi juga berkolaborasi dengan berbagai tim, melakukan riset teknologi, serta mengoptimalkan sistem agar lebih baik. Mereka juga harus memastikan bahwa setiap perubahan atau fitur baru dalam perangkat lunak dapat diimplementasikan tanpa mengganggu kestabilan sistem yang sudah ada. Secara keseluruhan, software engineer memiliki tanggung jawab yang lebih luas dibandingkan programmer karena mereka terlibat dalam seluruh siklus pengembangan perangkat lunak, mulai dari perencanaan hingga pemeliharaan sistem. Perbedaan Scope Pekerjaan Programmer dan Software Engineer di Startup vs. Perusahaan Besar Peran programmer dan software engineer bisa sangat berbeda tergantung pada skala perusahaan tempat mereka bekerja. Di startup, biasanya mereka harus menangani berbagai aspek pengembangan perangkat lunak secara fleksibel. Sementara di perusahaan besar seperti Google atau Microsoft, pekerjaan mereka lebih terstruktur dengan pembagian tugas yang jelas. 1. Scope Pekerjaan di Startup Di startup, baik programmer maupun software engineer sering kali harus mengerjakan berbagai tugas sekaligus. Karena sumber daya terbatas, mereka dituntut untuk lebih fleksibel dan bisa mengatasi berbagai tantangan teknis. Programmer di StartupMengembangkan fitur dari awal hingga selesai.Menulis kode untuk frontend, backend, atau bahkan full-stack.Menangani debugging dan perbaikan bug secara langsung.Bisa ikut serta dalam diskusi produk dan teknologi yang akan digunakan.Terkadang juga bertanggung jawab atas deployment dan pemeliharaan sistem.Software Engineer di StartupMerancang arsitektur sistem agar scalable dan efisien.Menentukan teknologi yang akan digunakan dalam pengembangan produk.Melakukan optimasi performa sistem dan database.Mengatur workflow pengembangan menggunakan metodologi seperti Agile atau Scrum.Bisa ikut terlibat dalam aspek keamanan dan DevOps jika tim masih kecil. Di startup, batas antara programmer dan software engineer sering kali tidak terlalu jelas karena keduanya harus fleksibel dan menangani banyak hal sekaligus. 2. Scope Pekerjaan di Perusahaan Besar (Google, Microsoft, dll.) Di perusahaan besar, peran programmer dan software engineer lebih terspesialisasi dan terstruktur. Setiap orang memiliki tanggung jawab spesifik sesuai dengan divisi atau timnya. Programmer di Perusahaan BesarFokus pada coding untuk bagian tertentu dari sistem atau produk.Bekerja dalam tim yang memiliki spesialisasi masing-masing (frontend, backend, atau mobile).Mengikuti standar code review dan best practices yang ketat.Tidak banyak terlibat dalam pengambilan keputusan arsitektur sistem.Memiliki akses ke tools dan sistem yang sudah matang dan stabil.Software Engineer di Perusahaan BesarTerlibat dalam perancangan arsitektur sistem yang kompleks dan skalabel.Menganalisis dan mengoptimalkan performa sistem di skala besar.Berkolaborasi dengan tim lintas departemen untuk mengintegrasikan berbagai layanan.Memastikan sistem yang dikembangkan sesuai dengan standar keamanan dan compliance perusahaan.Bisa bekerja dalam spesialisasi yang lebih sempit seperti Machine Learning Engineer, Security Engineer, atau Cloud Engineer. Di perusahaan besar, software engineer memiliki lebih banyak tanggung jawab strategis dalam pengembangan perangkat lunak dibandingkan programmer yang lebih fokus pada coding dan implementasi fitur. Kesimpulan Di startup, programmer dan software engineer sering kali memiliki peran yang lebih luas dan fleksibel karena keterbatasan tim dan sumber daya.Di perusahaan besar, peran mereka lebih terspesialisasi dan memiliki struktur kerja yang lebih formal dengan standar yang lebih ketat. Jika seorang pemula ingin belajar berbagai aspek software development dengan cepat, bekerja di startup bisa menjadi pilihan yang baik. Namun, jika ingin bekerja dalam lingkungan yang lebih terstruktur dengan standar tinggi, maka perusahaan besar seperti Google atau Microsoft bisa menjadi tujuan karir jangka panjang. Fokus Menjadi Programmer atau Software Engineer Saat Masih Kuliah? Bagi pemula yang masih kuliah dan ingin berkarir di dunia teknologi, pertanyaan yang sering muncul adalah apakah lebih baik fokus menjadi programmer atau software engineer. Keduanya memiliki peran penting dalam industri teknologi, tetapi jalur yang diambil bisa berbeda tergantung pada tujuan karir dan kesiapan dalam memahami konsep pengembangan perangkat lunak. Memulai dengan Programmer Jika masih dalam tahap awal belajar, lebih baik fokus menjadi programmer terlebih dahulu. Ini karena peran programmer lebih langsung berhubungan dengan coding dan pengembangan fitur dalam proyek perangkat lunak. Dengan menjadi programmer, pemula bisa: Meningkatkan pemahaman tentang bahasa pemrograman.Mendapat pengalaman dalam membangun aplikasi nyata.Mengenal berbagai tools dan teknologi yang digunakan dalam software development.Memahami cara kerja tim dalam pengembangan perangkat lunak. Berfokus pada programming di awal akan membantu pemula menguasai dasar-dasar yang sangat dibutuhkan sebelum melangkah ke tingkat yang lebih kompleks. Beralih ke Software Engineer Setelah memiliki pemahaman yang cukup tentang coding dan cara kerja pengembangan perangkat lunak, pemula bisa mulai mendalami software engineering. Peran ini membutuhkan pemahaman yang lebih luas, seperti: Merancang arsitektur sistem perangkat lunak.Memahami konsep algoritma, struktur data, dan skalabilitas sistem.Berkolaborasi dengan berbagai tim untuk mengembangkan solusi teknologi yang lebih kompleks. Beralih ke software engineering biasanya lebih cocok setelah memiliki pengalaman dalam programming, karena dibutuhkan pemahaman yang lebih mendalam tentang pengelolaan sistem perangkat lunak secara keseluruhan. Tips Menjadi Professional Programmer dan Software Engineer Menjadi seorang professional programmer atau software engineer bukan hanya tentang menguasai bahasa pemrograman, tetapi juga bagaimana menerapkan ilmu tersebut dalam proyek nyata. Berikut beberapa tips yang bisa membantu pemula berkembang menjadi profesional di bidang ini. 1. Belajar dengan Project-Based Learning Metode belajar berbasis proyek (project-based learning) sangat efektif untuk memahami konsep pemrograman dan software engineering secara langsung. Dengan membangun proyek nyata, pemula bisa: Menghadapi tantangan yang mirip dengan dunia kerja.Memahami cara mengimplementasikan teori ke dalam praktik.Belajar menyelesaikan masalah yang terjadi dalam pengembangan perangkat lunak. Platform seperti BuildWithAngga menyediakan kursus berbasis proyek yang mengajarkan cara membangun aplikasi dari awal hingga selesai. Ini sangat bermanfaat untuk meningkatkan keterampilan teknis sekaligus membangun portofolio yang bisa digunakan saat melamar kerja. 2. Belajar dari Mentor dan Komunitas Bimbingan dari mentor yang sudah berpengalaman bisa mempercepat proses belajar. Beberapa manfaat belajar dari mentor atau komunitas seperti di BuildWithAngga adalah: Mendapatkan arahan dan feedback langsung dari profesional di industri.Belajar strategi dan praktik terbaik dalam pemrograman dan software engineering.Berkesempatan membangun relasi dengan orang-orang di industri teknologi. Selain itu, aktif dalam komunitas pemrograman seperti forum, grup diskusi, atau event coding juga bisa membantu memperluas wawasan dan mendapatkan peluang baru. 3. Kuasai Fundamental dan Struktur Data Baik sebagai programmer maupun software engineer, pemahaman terhadap fundamental pemrograman sangat penting. Ini termasuk: Algoritma dan struktur data.Paradigma pemrograman seperti OOP (Object-Oriented Programming) dan Functional Programming.Konsep database dan sistem backend. Memahami dasar-dasar ini akan memudahkan dalam mengembangkan aplikasi yang lebih kompleks di masa depan. 4. Gunakan Version Control System (Git) Seorang profesional di bidang ini harus terbiasa dengan Git dan platform seperti GitHub atau GitLab. Ini sangat penting untuk: Mengelola kode secara terstruktur.Bekerja secara kolaboratif dengan tim.Melakukan tracking perubahan kode dan rollback jika terjadi kesalahan. 5. Bangun Portofolio dan Ikut Open Source Portofolio sangat berperan dalam menunjukkan keterampilan kepada calon perekrut atau klien. Beberapa cara membangun portofolio yang kuat: Membuat proyek pribadi seperti website, aplikasi, atau sistem kecil.Berkontribusi ke proyek open source untuk mendapatkan pengalaman dalam pengembangan tim.Menampilkan hasil kerja di platform seperti GitHub, LinkedIn, atau website pribadi. 6. Pahami Cara Kerja Software Engineering Jika ingin menjadi software engineer, pemahaman tentang arsitektur sistem, desain database, dan metode pengembangan perangkat lunak seperti Agile atau DevOps sangat diperlukan. Mengikuti kursus atau bootcamp yang membahas aspek ini akan membantu meningkatkan kemampuan dalam membangun solusi perangkat lunak yang skalabel. 7. Terus Belajar dan Adaptasi Teknologi Baru Dunia teknologi selalu berkembang, sehingga programmer dan software engineer harus terus belajar dan beradaptasi. Beberapa cara yang bisa dilakukan: Mengikuti kursus online untuk update teknologi terbaru.Membaca dokumentasi resmi dari bahasa atau framework yang digunakan.Mengikuti perkembangan industri melalui blog, podcast, atau konferensi teknologi. Penutup dan Saran Baik programmer maupun software engineer adalah profesi yang sangat menjanjikan di era digital saat ini. Pemula yang masih kuliah atau baru memulai karir bisa fokus menjadi programmer terlebih dahulu untuk mengasah keterampilan coding dan memahami cara kerja software development. Setelah memiliki pengalaman dan pemahaman yang lebih luas, barulah bisa berkembang menjadi software engineer yang berperan dalam perancangan dan pengelolaan sistem perangkat lunak. Untuk mempercepat proses belajar dan mendapatkan pengalaman yang lebih praktis, sangat disarankan untuk belajar dengan metode project-based learning bersama mentor expert. Salah satu platform yang bisa dicoba adalah BuildWithAngga, yang menawarkan berbagai manfaat seperti: ✅ Akses selamanya ke materi dan kelas, sehingga bisa belajar sesuai ritme sendiri. ✅ Portofolio berkualitas yang bisa digunakan untuk melamar kerja atau mendapatkan proyek freelance. ✅ Konsultasi dengan mentor untuk mendapatkan insight dan bimbingan langsung dari para expert di industri. Belajar dengan pendekatan yang tepat dan bimbingan dari mentor akan membuat perjalanan menjadi professional programmer atau software engineer lebih terarah dan efektif. Jangan ragu untuk mulai sekarang dan terus eksplorasi dunia teknologi! 🚀

Kelas Apa itu Node JS, V8, dan HTTP Server Pada Website Development di BuildWithAngga

Apa itu Node JS, V8, dan HTTP Server Pada Website Development

Di era digital saat ini, website modern menjadi kebutuhan utama bagi bisnis dan individu. Website modern bukan hanya tentang tampilannya yang menarik, tetapi juga bagaimana situs tersebut memberikan pengalaman yang optimal bagi pengguna. Pengguna cenderung mengharapkan website yang cepat, responsif, dan mudah diakses di berbagai perangkat seperti smartphone, tablet, dan desktop. Website modern harus mengutamakan kecepatan, karena pengguna cenderung meninggalkan situs yang membutuhkan waktu lebih dari beberapa detik untuk dimuat. Selain itu, responsivitas atau kemampuan website menyesuaikan tampilannya dengan perangkat yang digunakan sangat penting. Dengan responsivitas yang baik, pengguna dapat menikmati pengalaman browsing yang nyaman tanpa perlu melakukan zoom in atau scroll horizontal. Apa Itu Node.js, V8, dan HTTP Server? Pentingnya Bagi Backend Developer Node.js adalah platform open-source yang memungkinkan developer menjalankan JavaScript di sisi server. Sebelum adanya Node.js, JavaScript umumnya hanya digunakan untuk pengembangan frontend. Dengan Node.js, JavaScript dapat digunakan untuk mengelola logic backend seperti pengelolaan database, pengolahan request, dan pengiriman response ke client. Node.js dibangun di atas V8, sebuah engine JavaScript yang dikembangkan oleh Google. V8 bertanggung jawab untuk mengonversi kode JavaScript menjadi kode mesin (machine code) yang dapat dijalankan langsung oleh komputer. Dengan performa tinggi dari V8, Node.js dapat menangani tugas-tugas berat dengan cepat dan efisien. Salah satu fitur utama Node.js adalah kemampuannya untuk membangun HTTP server. HTTP server adalah komponen yang bertugas menerima request dari client (seperti browser) dan mengirimkan response. Dalam Node.js, developer dapat dengan mudah membuat HTTP server tanpa perlu menggunakan software tambahan. Hal ini membuat Node.js menjadi pilihan populer untuk membangun aplikasi web yang ringan dan scalable. Sekilas Soal Evolusi JavaScript: Dari Frontend ke Backend JavaScript awalnya dikenal sebagai bahasa pemrograman yang hanya digunakan untuk pengembangan frontend. Di era 1990-an, JavaScript lahir sebagai cara untuk membuat website menjadi lebih interaktif, seperti menambahkan animasi, validasi form, atau efek hover pada elemen tertentu. Semua proses tersebut berjalan langsung di browser pengguna, menjadikan JavaScript fokus pada manipulasi elemen di sisi client. Namun, seiring waktu, kebutuhan pengembangan web semakin kompleks. Developer mulai mencari cara untuk menggunakan JavaScript tidak hanya di sisi frontend tetapi juga di backend. Hal ini memungkinkan mereka untuk mengelola server, database, dan logic aplikasi tanpa harus berpindah ke bahasa pemrograman lain seperti PHP atau Python. Terobosan besar terjadi ketika Node.js diperkenalkan pada tahun 2009. Dengan Node.js, JavaScript mendapatkan kemampuan untuk berjalan di luar browser, tepatnya di server. Ini mengubah cara kerja web development secara keseluruhan, memungkinkan developer menggunakan satu bahasa untuk mengembangkan aplikasi secara menyeluruh, baik frontend maupun backend. Pendekatan ini sering disebut sebagai full-stack JavaScript development. Penjelasan Singkat tentang Analogi Restoran Bayangkan sebuah restoran untuk memahami bagaimana aplikasi web bekerja. Dalam analogi ini: Frontend adalah bagian restoran yang dilihat oleh pelanggan. Ini mencakup meja, kursi, menu, dan dekorasi. Frontend bertugas memberikan pengalaman yang menyenangkan kepada pelanggan, sama seperti tampilan website yang memikat dan mudah digunakan.Backend adalah dapur restoran. Pelanggan tidak melihat apa yang terjadi di dapur, tetapi di sanalah proses inti berlangsung. Mulai dari menerima pesanan, menyiapkan makanan, hingga menyajikan hidangan kepada pelanggan. Dalam konteks web, backend adalah tempat di mana data diproses, permintaan dikelola, dan jawaban diberikan ke frontend.Server adalah pelayan restoran yang menghubungkan pelanggan dengan dapur. Ketika pelanggan memesan makanan, pelayan mencatat pesanan tersebut, menyampaikannya ke dapur, lalu membawa makanan yang sudah jadi ke meja pelanggan. Dalam aplikasi web, server bertugas menerima permintaan (request) dari browser pengguna, memprosesnya di backend, lalu mengirimkan hasilnya kembali ke browser. Fungsi Utama HTTP Server HTTP server adalah salah satu komponen penting dalam sistem web. Fungsinya adalah sebagai jembatan antara klien (biasanya browser atau aplikasi frontend) dan server backend, memungkinkan komunikasi yang efisien. Untuk memahaminya lebih jelas, berikut adalah penjelasan detail dari fungsi utama HTTP server dengan analogi restoran: 1. Menerima Request dari Klien (Seperti Pelanggan Memesan Menu) Ketika seseorang membuka website, browser mereka mengirimkan permintaan (request) ke server. Permintaan ini biasanya berupa informasi tentang apa yang diinginkan pengguna, seperti membuka halaman tertentu, mengunduh file, atau mendapatkan data tertentu. Dalam analogi restoran, ini seperti pelanggan datang ke restoran dan memesan makanan melalui pelayan. Pelanggan bisa meminta makanan tertentu dari menu, meminta rekomendasi, atau bahkan mengajukan pertanyaan spesifik tentang bahan makanan. HTTP server bertindak sebagai pelayan yang mencatat setiap permintaan dari pelanggan. 2. Memproses Request (Seperti Memasak Pesanan di Dapur) Setelah request diterima, HTTP server memproses permintaan tersebut dengan cara meneruskannya ke backend atau sumber daya yang sesuai. Proses ini bisa melibatkan berbagai hal seperti mengambil data dari database, memproses logic bisnis, atau menjalankan fungsi tertentu. Dalam restoran, ini seperti pelayan menyampaikan pesanan pelanggan ke dapur. Dapur kemudian mempersiapkan makanan sesuai dengan pesanan. Jika pesanan membutuhkan bahan yang rumit atau banyak langkah, waktu pemrosesan bisa lebih lama, tetapi tetap harus efisien agar pelanggan tidak menunggu terlalu lama. 3. Mengirim Respons ke Klien (Seperti Menghidangkan Makanan ke Meja) Setelah server selesai memproses permintaan, hasilnya dikirim kembali ke klien dalam bentuk respons. Respons ini bisa berupa halaman website, data JSON, file, atau bahkan pesan error jika ada masalah. Dalam analogi restoran, ini seperti pelayan membawa makanan yang sudah dimasak ke meja pelanggan. Respons harus sesuai dengan pesanan pelanggan dan disajikan dengan cara yang mudah dipahami (misalnya, makanan disajikan dalam piring yang rapi). Dalam konteks web, respons juga harus dikemas dengan format yang sesuai, seperti HTML untuk website atau JSON untuk API. Pentingnya HTTP Server yang Efisien Sama seperti restoran yang membutuhkan pelayan profesional dan dapur yang terorganisir, HTTP server harus mampu menangani permintaan dengan cepat dan akurat. Server yang lambat atau tidak responsif akan membuat pengguna frustrasi, sama seperti pelanggan yang terlalu lama menunggu makanan di restoran. Dengan fungsi-fungsi ini, HTTP server menjadi tulang punggung komunikasi antara klien dan backend, memastikan pengalaman pengguna berjalan lancar dan menyenangkan. Perbedaan V8 dan WebAssembly (Wasm) Dalam dunia web development modern, performa adalah kunci utama, terutama ketika berbicara tentang aplikasi yang membutuhkan komputasi berat seperti game, pengolahan data besar, atau simulasi kompleks. Di sinilah V8 dan WebAssembly (Wasm) memainkan peran penting, masing-masing dengan keunggulan dan fungsinya sendiri. Berikut penjelasan detailnya: Apa Itu WebAssembly (Wasm)? WebAssembly, atau sering disingkat Wasm, adalah format biner yang dirancang untuk menjalankan kode dengan performa tinggi di browser. Wasm memungkinkan developer menggunakan bahasa pemrograman selain JavaScript, seperti C, C++, atau Rust, untuk membangun aplikasi web. Kode tersebut kemudian dikompilasi menjadi format biner yang sangat efisien dan dijalankan langsung oleh browser. Bayangkan aplikasi seperti game 3D berbasis web, software editing video, atau pengolahan data besar. Tugas-tugas berat seperti ini sering kali terlalu lambat jika hanya menggunakan JavaScript. Dengan Wasm, browser bisa menjalankan kode yang lebih mendekati kecepatan kode asli (native) yang biasanya hanya bisa dijalankan di desktop. Peran dan Fungsi V8 Di sisi lain, V8 adalah engine JavaScript yang dikembangkan oleh Google. V8 bertugas untuk menjalankan kode JavaScript secara efisien. Ia mengubah kode JavaScript menjadi kode mesin (machine code) agar bisa langsung dijalankan oleh perangkat keras komputer. V8 menjadi pondasi di balik performa tinggi JavaScript, terutama di aplikasi modern seperti single-page applications (SPA) atau aplikasi real-time. Perbedaan Utama V8 dan Wasm Bahasa yang DidukungV8 hanya mendukung JavaScript. Semua kode JavaScript yang ditulis developer akan dijalankan melalui V8.Wasm dirancang untuk mendukung berbagai bahasa pemrograman. Developer dapat menggunakan bahasa seperti C atau Rust, lalu mengompilasinya ke format Wasm agar dapat dijalankan di browser.Fokus UtamaV8 fokus pada menjalankan JavaScript dengan efisien. Engine ini sangat dioptimalkan untuk tugas-tugas yang biasa dilakukan JavaScript, seperti manipulasi DOM, animasi, atau pengelolaan data sederhana.Wasm fokus pada tugas berat yang membutuhkan performa tinggi, seperti komputasi ilmiah, game 3D, atau pengolahan video. Wasm dibuat untuk melengkapi JavaScript, bukan menggantikannya.Analoginya: Kompor vs Alat Masak Tambahan Jika V8 diibaratkan sebagai kompor utama, maka Wasm adalah alat masak tambahan seperti oven atau blender. Kompor sangat baik untuk memasak tugas sehari-hari, tetapi jika Anda ingin membuat hidangan yang kompleks atau tugas berat, alat tambahan seperti oven akan sangat membantu. Begitu pula, JavaScript melalui V8 cukup untuk sebagian besar aplikasi web, tetapi untuk tugas berat, Wasm hadir untuk mendukung. Mengapa Wasm Penting? WebAssembly membuka peluang baru bagi web development, memungkinkan browser menjalankan tugas berat yang sebelumnya dianggap mustahil. Dengan kombinasi JavaScript (V8) untuk tugas sehari-hari dan Wasm untuk tugas berat, developer dapat membangun aplikasi web yang lebih canggih, efisien, dan performa tinggi. Kesimpulannya, V8 dan Wasm adalah dua teknologi yang saling melengkapi. V8 memastikan JavaScript berjalan cepat dan efisien, sementara Wasm memungkinkan aplikasi web menangani tugas berat dengan performa mendekati native. Kombinasi keduanya memungkinkan browser menjadi platform yang lebih kuat untuk aplikasi modern. HTTP Server denggan Node JS Berikut adalah contoh sederhana bagaimana membuat HTTP server menggunakan modul bawaan http di Node.js: // Import modul bawaan 'http' const http = require('http'); // Buat server dengan fungsi untuk menangani request dan response const server = http.createServer((req, res) => { // Tetapkan status kode dan header response res.writeHead(200, { 'Content-Type': 'text/plain' }); // Kirimkan respons ke klien res.end('Hello, World! Ini adalah server Node.js sederhana.'); }); // Tetapkan port untuk server const PORT = 3000; // Jalankan server dan tampilkan pesan saat server aktif server.listen(PORT, () => { console.log(`Server berjalan di <http://localhost>:${PORT}`); }); Penjelasan Kode: Import Modul http Node.js memiliki modul bawaan bernama http yang digunakan untuk membuat server HTTP. Modul ini diimpor menggunakan require('http').Membuat Server Fungsi http.createServer() digunakan untuk membuat server. Fungsi ini menerima callback dengan dua parameter:req: Objek yang merepresentasikan request dari klien.res: Objek yang digunakan untuk mengirimkan response ke klien.Mengatur Responseres.writeHead(200, { 'Content-Type': 'text/plain' }): Mengatur status HTTP ke 200 (OK) dan menyetel header content type ke text/plain.res.end(): Mengirimkan response ke klien dan mengakhiri proses penanganan request.Menjalankan Server Server dijalankan menggunakan metode listen() dengan port yang ditentukan. Dalam contoh ini, server dijalankan pada port 3000. Saat server aktif, pesan akan ditampilkan di terminal. Cara Menjalankan: Pastikan Node.js terinstal di komputer Anda.Simpan kode di atas ke dalam file, misalnya server.js. Jalankan file dengan perintah berikut di terminal: node server.js Buka browser dan akses http://localhost:3000. Anda akan melihat pesan "Hello, World! Ini adalah server Node.js sederhana.". Dengan contoh sederhana ini, Anda telah berhasil membuat HTTP server pertama Anda menggunakan Node.js! Contoh aplikasi menarik dapat dibangun dnegan Node JS 1. Aplikasi Real-Time Chat Node.js sangat cocok untuk membangun aplikasi real-time, seperti platform chat. Dengan pendekatan event-driven dan non-blocking I/O, Node.js memungkinkan komunikasi dua arah antara klien dan server secara efisien. Fitur seperti pesan instan, notifikasi langsung, atau integrasi video call dapat diimplementasikan dengan memanfaatkan library seperti Socket.io. Node.js dapat menangani ribuan koneksi secara bersamaan tanpa membebani server, menjadikannya pilihan ideal untuk aplikasi yang memerlukan interaksi real-time, seperti aplikasi perpesanan pribadi, chat grup, atau bahkan obrolan untuk layanan pelanggan. 2. API Backend untuk Aplikasi E-Commerce Node.js adalah pilihan populer untuk membangun RESTful API yang mendukung aplikasi e-commerce. API ini dapat digunakan untuk mengelola produk, pesanan, pengguna, hingga sistem pembayaran. Dengan Node.js, Anda dapat membangun backend yang cepat dan scalable untuk menangani permintaan seperti: Pencarian produk berdasarkan kategori.Penambahan produk ke keranjang belanja.Pemrosesan pembayaran secara real-time.xx Node.js juga dapat diintegrasikan dengan database modern seperti MongoDB atau PostgreSQL, memungkinkan pengelolaan data yang efisien untuk jumlah pengguna yang terus bertambah. Selain itu, performa tinggi Node.js membantu menangani lonjakan traffic selama kampanye promosi atau penjualan besar. 3. Aplikasi Streaming Media Node.js sangat cocok untuk membangun aplikasi streaming media, seperti platform untuk video atau musik. Dengan kemampuan untuk menangani data dalam bentuk streaming, Node.js memungkinkan server mengirimkan data secara bertahap ke klien tanpa perlu memuat seluruh file sekaligus. Contoh aplikasi yang bisa dibangun: Platform streaming video seperti YouTube.Layanan streaming musik seperti Spotify.Aplikasi berbagi file atau dokumen secara real-time.a Fitur ini sangat efisien untuk pengguna dengan koneksi internet terbatas karena mereka dapat mulai mengakses konten meskipun file belum diunduh sepenuhnya. Node.js juga mendukung integrasi dengan Content Delivery Network (CDN) untuk meningkatkan kecepatan dan kualitas layanan streaming. Dengan arsitektur non-blocking, Node.js dapat menangani permintaan besar secara bersamaan, membuatnya ideal untuk aplikasi yang memiliki banyak pengguna aktif secara bersamaan. Kesimpulan dan Saran untuk Pemula Belajar web development, terutama dengan teknologi modern seperti Node.js, bisa menjadi tantangan besar bagi pemula. Namun, dengan panduan yang tepat, proses ini dapat menjadi jauh lebih mudah dan efektif. Salah satu cara terbaik untuk mempercepat pembelajaran adalah dengan belajar dari mentor yang sudah expert di bidangnya, seperti di platform BuildWithAngga. Mengapa Belajar di BuildWithAngga? BuildWithAngga menawarkan banyak keunggulan yang dapat membantu Anda mengembangkan keterampilan dan karir di bidang teknologi: Akses Seumur Hidup Dengan akses seumur hidup ke semua materi pembelajaran, Anda bisa belajar kapan saja dan di mana saja sesuai dengan kecepatan Anda sendiri. Ini adalah keuntungan besar, terutama bagi mereka yang memiliki jadwal sibuk atau ingin belajar secara bertahap.Konsultasi Karir Selain belajar teknis, Anda juga mendapatkan kesempatan untuk berkonsultasi langsung dengan mentor mengenai karir. Apakah Anda ingin menjadi developer full-stack, backend specialist, atau bahkan memulai startup teknologi, mentor akan membantu Anda memahami langkah-langkah yang diperlukan untuk mencapai tujuan tersebut.Portfolio Berkualitas Dalam industri teknologi, portfolio adalah aset utama. Dengan bimbingan mentor expert, Anda akan belajar membuat proyek-proyek berkualitas yang sesuai dengan standar industri. Portfolio ini tidak hanya menunjukkan kemampuan Anda, tetapi juga menjadi bukti nyata keahlian Anda kepada calon pemberi kerja atau klien. Saran untuk Pemula Jika Anda baru memulai perjalanan belajar coding dan web development: Fokuslah pada satu teknologi atau bahasa terlebih dahulu, seperti JavaScript dan Node.js.Manfaatkan mentor untuk menjawab pertanyaan, memperbaiki kesalahan, dan memberikan saran berdasarkan pengalaman nyata di industri.Kerjakan proyek nyata untuk mengasah keterampilan dan mengisi portfolio Anda.Jangan ragu untuk berkonsultasi tentang langkah karir Anda, baik itu mencari pekerjaan atau membangun bisnis sendiri. Dengan bimbingan mentor expert di BuildWithAngga, Anda tidak hanya belajar teori, tetapi juga mendapatkan wawasan praktis yang relevan dengan dunia kerja. Mulailah perjalanan Anda hari ini dan buka peluang karir yang lebih luas di masa depan!

Kelas Belajar Mengenal Views Pada Framework Laravel 11 Sebagai Pemula di BuildWithAngga

Belajar Mengenal Views Pada Framework Laravel 11 Sebagai Pemula

MVC adalah singkatan dari Model-View-Controller, sebuah pola arsitektur yang memisahkan logika aplikasi menjadi tiga bagian utama: Model untuk logika data, View untuk antarmuka pengguna, dan Controller untuk mengatur alur aplikasi. Dalam artikel ini, kita akan membahas bagian View, yaitu komponen yang berfungsi menampilkan data kepada pengguna. Semua elemen antarmuka seperti halaman HTML, layout, atau komponen front-end dikelola melalui View. Membuat Proyek Laravel 11 Sebelum belajar lebih jauh tentang View, langkah pertama adalah membuat proyek Laravel 11 terbaru. Pastikan Anda sudah memiliki Composer di komputer Anda, karena ini adalah alat utama untuk menginstal framework Laravel. Untuk memulai, buka terminal atau command prompt dan gunakan perintah berikut: composer create-project laravel/laravel nama-proyek-anda Setelah instalasi selesai, pindah ke folder proyek dengan perintah: cd nama-proyek-anda Jalankan server bawaan Laravel dengan perintah: php artisan serve Jika server berhasil berjalan, Anda bisa membuka URL proyek di browser, biasanya http://127.0.0.1:8000. Struktur Folder View Di Laravel, file View disimpasn di dalam folder resources/views. Folder ini adalah tempat semua file Blade template diletakkan. Blade adalah templating engine Laravel yang menyediakan sintaks sederhana untuk mengelola View. Sebagai contoh, untuk membuat file View baru, Anda bisa membuat file welcome.blade.php di dalam folder resources/views. Isi file tersebut dengan kode berikut: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Selamat Datang</title> </head> <body> <h1>Halo, Selamat Datang di Laravel 11!</h1> <p>Ini adalah halaman view pertama Anda.</p> </body> </html> Untuk menampilkan View ini, buka file routes/web.php dan ubah kode defaultnya menjadi: use Illuminate\\Support\\Facades\\Route; Route::get('/', function () { return view('welcome'); }); Setelah itu, buka kembali URL proyek Anda di browser, dan Anda akan melihat halaman View yang telah dibuat. Apa Itu Blade Directive? Blade directive adalah fitur bawaan dari templating engine Laravel yang menyediakan sintaks sederhana untuk mempermudah pembuatan tampilan pada file View. Dengan menggunakan Blade directives, developer dapaat menulis logika PHP di dalam file View tanpa harus menuliskan kode PHP mentah secara langsung, sehingga membuat kode lebih bersih, terstruktur, dan mudah dipahami. Blade directives membantu developer untuk menangani berbagai tugas umum seperti perulangan, pengkondisian, dan rendering data dengan cara yang efisien. Dengan kemampuannya ini, Blade sangat membantu dalam pengembangan proyek web, termasuk proyek kompleks seperti website apotek online. Contoh Penggunaan Blade Directive pada Website Apotek Online Menampilkan Daftar Obat Pada sebuah apotek online, Anda bisa menggunakan Blade directive @foreach untuk menampilkan daftar obat dari database. // Controller use App\\Models\\Medicine; public function index() { $medicines = Medicine::all(); return view('medicines.index', compact('medicines')); } <!-- View: resources/views/medicines/index.blade.php --> <h1>Daftar Obat</h1> <ul> @foreach ($medicines as $medicine) <li>{{ $medicine->name }} - {{ $medicine->price }} IDR</li> @endforeach </ul> Menampilkan Pesan Error atau Sukses Blade directive @if digunakan untuk memerikasa dan menampilkan pesan tertentu berdasarkan kondisi, seperti ketika transaksi berhasil atau gagal. <!-- View --> @if (session('success')) <div class="alert alert-success"> {{ session('success') }} </div> @endif @if (session('error')) <div class="alert alert-danger"> {{ session('error') }} </div> @endif Menyembunyikan Konten Berdasarkan Peran Pengguna Dengan Blade directive @can, Anda bisa membatasi akses ke fitur tertentu berdasarkan peran pengguna, seperti hanya admin yang bisa menambahkan obat. <!-- View --> @can('add-medicine') <a href="{{ route('medicines.create') }}" class="btn btn-primary">Tambah Obat</a> @endcan Menampilkan Formulir Pemesanan Obat Blade directive @csrf memastikan keamanan formulair dengan menambahkan token CSRF secara otomatis. <!-- View --> <form action="{{ route('orders.store') }}" method="POST"> @csrf <label for="medicine">Pilih Obat:</label> <select name="medicine" id="medicine"> @foreach ($medicines as $medicine) <option value="{{ $medicine->id }}">{{ $medicine->name }}</option> @endforeach </select> <button type="submit">Pesan</button> </form> Menampilkan Data dalam Tabel Blade directive @empty digunakan untuk memeriksa apakaah data kosong dan menampilkan pesan alternatif jika data tidak tersedia. <!-- View --> <table> <thead> <tr> <th>Nama Obat</th> <th>Harga</th> </tr> </thead> <tbody> @forelse ($medicines as $medicine) <tr> <td>{{ $medicine->name }}</td> <td>{{ $medicine->price }} IDR</td> </tr> @empty <tr> <td colspan="2">Tidak ada obat tersedia saat ini.</td> </tr> @endforelse </tbody> </table> Blade directives sanagat membantu developrer dalam menulis logika View dengan lebih rapi dan efisien. Dengan penggunaannya, Anda dapat menghemat waktu dan tenaga dalam membangun fitur-fitur kompleks pada aplikasi, seperti sistem apotek online. Pastikan untuk terus mengeksplorasi dokumentasi Laravel untuk memahami lebih banyak Blade directives yang bisa digunakan. Bagian Layout pada Laravel Dalam Laravel, layout digunakan untuk mengatur kerangka dasar halaman sehingga kode yang berulang, seperti header, footer, dan navigasi, tidak perlu ditulis berulang kali di setiap file View. Layout disimpan dalam folder resources/views dan biasanya menggunakan file Blade. Misalnya, layout utama untuk website apotek online dapat disimpan di file resources/views/layouts/app.blade.php dan berisi struktur HTML dasar: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>@yield('title')</title> </head> <body> <header> <h1>Apotek Online</h1> @include('partials.navbar') </header> <main> @yield('content') </main> <footer> <p>© 2024 Apotek Online</p> </footer> </body> </html> File layout ini kemudian dapat digunakan oleh View lainnya dengan Blade directive @extends. Passing Data ke View Data dari controller dikirimkan ke View menggunakan metode with atau compact. Misalnya, Anda ingin mengirim daftar obat ke halaman: // Controller use App\\Models\\Medicine; public function index() { $medicines = Medicine::all(); return view('medicines.index', compact('medicines')); } Data medicines kemudian dapat diakses di file View: @extends('layouts.app') @section('title', 'Daftar Obat') @section('content') <h2>Daftar Obat</h2> <ul> @foreach ($medicines as $medicine) <li>{{ $medicine->name }} - {{ $medicine->price }} IDR</li> @endforeach </ul> @endsection Menggunakan @include Blade directive @include memungkinkan Anda untuyk menyisipkan file View lainnya ke dalam sebuah halaman. Ini berguna untuk komponen yang sering digunakan, seperti navbar atau formulir. Misalnya, buat file resources/views/partials/navbar.blade.php: <nav> <ul> <li><a href="/">Beranda</a></li> <li><a href="/medicines">Obat</a></li> <li><a href="/contact">Kontak</a></li> </ul> </nav> File ini bisa dimasukkan ke dalam layout utama atau View lainnya: @include('partials.navbar') Proses Debugging Untuk mempermudah debugging, Laravel menyediakan fungsi dd() (dump and die) dan @dump untuk menampilkan data atau variabel secara jelas. Misalnya, jika Anda ingin memeriksa data yang dikirim ke View: // Controller public function index() { $medicines = Medicine::all(); dd($medicines); } Atau gunakan @dump di View: @extends('layouts.app') @section('content') @dump($medicines) @endsection Contoh Penggunaan pada Website Apotek Online Layout Halaman Detail Obat @extends('layouts.app') @section('title', 'Detail Obat') @section('content') <h2>{{ $medicine->name }}</h2> <p>Harga: {{ $medicine->price }} IDR</p> <p>Deskripsi: {{ $medicine->description }}</p> @endsection Formulir Pembelian Obat dengan @include Buat file formulir di resources/views/partials/order-form.blade.php: <form action="{{ route('orders.store') }}" method="POST"> @csrf <input type="hidden" name="medicine_id" value="{{ $medicine->id }}"> <button type="submit">Pesan Sekarang</button> </form> Sisipkan formulir ini di halaman detail obat: @extends('layouts.app') @section('content') <h2>{{ $medicine->name }}</h2> @include('partials.order-form') @endsection Menampilkan Pesan Flash dengan Passing Data // Controller public function store(Request $request) { // Logika penyimpanan pesanan return redirect()->route('orders.index')->with('success', 'Pesanan berhasil dibuat!'); } @if (session('success')) <div class="alert alert-success">{{ session('success') }}</div> @endif Tabel Obat dengan Layout @extends('layouts.app') @section('content') <table> <thead> <tr> <th>Nama Obat</th> <th>Harga</th> </tr> </thead> <tbody> @foreach ($medicines as $medicine) <tr> <td>{{ $medicine->name }}</td> <td>{{ $medicine->price }}</td> </tr> @endforeach </tbody> </table> @endsection Debugging Data dengan @dump @extends('layouts.app') @section('content') @dump($medicines) @endsection Dengan memanfaatkan fitur layout, passing data, @include, dan proses debugging, Laravel membuat pengembangan aplikasi web seperti apotek online menjadi lebih cepat dan efisien. Semua fitur ini mendukung struktur kode yang rapi dan mudah dipelihara. Blade Components pada Laravel Blade components adalah fiture yang memungkinkan Anda membuat elemen UI yang dapat digunakan kembali, sehingga mempercepat pengembangan dan memastikan konsistensi desain. Dalam proyek website apotek online, Blade componentes sangat cocok untuk elemen-elemen seperti kartu produk, tombol, atau komponen formulir yang sering digunakan. Membuat Kartu Produk untuk Menampilkan Informasi Obat Buat file Blade component dengan menjalankan perintah berikut di terminal: php artisan make:component MedicineCard Laravel akan membuat dua file: app/View/Components/MedicineCard.php untuk logika komponen.resources/views/components/medicine-card.blade.php untuk tampilan komponen. Isi file MedicineCard.php dengan logika data yang dibutuhkan: <?php namespace App\\View\\Components; use Illuminate\\View\\Component; class MedicineCard extends Component { public $medicine; public function __construct($medicine) { $this->medicine = $medicine; } public function render() { return view('components.medicine-card'); } } Edit file Blade di resources/views/components/medicine-card.blade.php untuk mendefinisikan tampilan kartu obat: <div class="medicine-card"> <h3>{{ $medicine->name }}</h3> <p>Harga: {{ $medicine->price }} IDR</p> <p>Stok: {{ $medicine->stock }}</p> <a href="/medicines/{{ $medicine->id }}" class="btn btn-primary">Detail</a> </div> Gunakan komponen ini di file View utama, misalnya pada halaman daftar obat: @extends('layouts.app') @section('content') <h1>Daftar Obat</h1> <div class="medicine-list"> @foreach ($medicines as $medicine) <x-medicine-card :medicine="$medicine" /> @endforeach </div> @endsection Membuat Tombol dengan Gaya Konsisten Buat component tombol untuk memastikan gaya konsisten di seluruh aplikasi. Jalankan perintah berikut: php artisan make:component Button Edit file app/View/Components/Button.php untuk menerima parameter teks tombol dan tautan: <?php namespace App\\View\\Components; use Illuminate\\View\\Component; class Button extends Component { public $text; public $link; public function __construct($text, $link = '#') { $this->text = $text; $this->link = $link; } public function render() { return view('components.button'); } } Edit file resources/views/components/button.blade.php untuk mendefinisikan tampilan tombol: <a href="{{ $link }}" class="btn btn-primary"> {{ $text }} </a> Gunakan komponen tombol ini di View lain. Misalnya, tambahkan tombol "Tambah Obat" di halaman admin: @extends('layouts.app') @section('content') <h1>Manajemen Obat</h1> <x-button text="Tambah Obat" link="/medicines/create" /> @endsection Penyesuaian Tambahan Blade components mendukung slot, atribut dinamis, dan default values. Anda bisa menambahkan logika tambahan seperti slot untuk fleksibilitas konten tombol: <a href="{{ $link }}" class="btn btn-primary {{ $attributes->get('class') }}"> {{ $slot ?? $text }} </a> Penggunaan di View: <x-button link="/medicines/create" class="btn-large"> <strong>Tambah Obat</strong> </x-button> Hasil ini membuat komponen Blade lebih fleksibel dan modular, sehingga sangat membantu dalam membangun aplikasi besar seperti website apotek online. Kesimpulan Laravel menyediakan berbagai fitur canggih seperti Blade components yang sangat membantu developer dalam menciptakan elemen UI yang modular, efisien, dan konsisten. Dengan memahami dan menerapkan konsep ini, pengembangan aplikasi web seperti website apotek online menjadi lebih terstruktur dan cepat. Selain itu, Laravel juga mendukung pengembangan komponen lain seperti validasi, routing, dan autentikasi, sehingga sangat cocok untuk proyek skala kecil hingga besar. Saran untuk Web Developer Pemula Bagi web developer pemula yang ingin mempersiapkan karir lebih baik di dunia web development, belajar bersama mentor expert adalah langkah yang sangat direkomendasikan. Platform seperti BuildWithAngga menawarkan: Akses Materi Seumur Hidup: Anda bisa mempelajari semua kursus kapan saja tanpa batas waktu.Portfolio Berkualitas: Dalam kursus, Anda akan dibimbing untuk menghasilkan portfolio yang menarik dan relevan dengan kebutuhan industri.Konsultasi Karir: Selain belajar, Anda juga bisa mendapatkan arahan karir yang sesuai dengan tujuan Anda melalui sesi konsultasi dengan mentor expert.a Dengan belajar bersama mentor, Anda tidak hanya akan memahami teknik coding yang baik tetapi juga mempersiapkan diri untuk menghadapi tantangan dunia kerja dengan percaya diri. Tingkatkan skill Anda, hasilkan karya yang membanggakan, dan mulai bangun karir yang lebih baik di dunia web development!