flash sale
hamburger-menu

Tips All

Meningkatkan skills menjadi 1% lebih baik

Reset
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!

Kelas Belajar Mengenal Class HTTP Response Pada Framework Laravel 11 di BuildWithAngga

Belajar Mengenal Class HTTP Response Pada Framework Laravel 11

Dalam dunia web development, salah satu tugas utama seorang developer adalah menangani HTTP request dan response. Proses ini bisa sangat kompleks jika harus dikerjakan tanpa bantuan framework. Untungnya, Laravel hadir untuk menyederhanakan pekerjaan ini. Framework Laravel menyediakan berbagai fitur bawaan yang mempermudah developer untuk menangani request dari browser, seperti data yang dikirim pengguna melalui form, serta memberikan response yang sesuai. Dengan menggunakan Laravel, developer tidak perlu repot mengurus detail teknis yang rumit. Semua proses ini dibuat lebih ringkas dan efisien, sehingga developer bisa fokus pada hal-hal yang lebih penting, seperti membangun fitur atau meningkatkan pengalaman pengguna. Apa Itu Class Response dalam Framework Laravel? Dalam Laravel, salah satu komponen penting yang sering digunakan adalah class Response. Class ini digunakan untuk mengelola bagaimana aplikasi memberikan balasan (response) kepada pengguna setelah menerima request. Mulai dari mengirim halaman HTML, file JSON, hingga file yang bisa di-download, semua dapat diatur dengan mudah menggunakan class ini. Sebagai analogi, bayangkan Anda berada di sebuah restoran. Saat Anda memesan makanan (request), pelayan akan menyampaikan pesanan Anda ke dapur dan kemudian membawa makanan tersebut ke meja Anda (response). Dalam konteks Laravel, class Response bertindak seperti pelayan restoran yang bertugas memastikan bahwa makanan (data) yang Anda pesan sampai ke meja Anda dengan baik dan sesuai dengan permintaan. Dengan memahami bagaimana Laravel menangani response menggunakan class Response, developer dapat mengatur bagaimana data dikirimkan ke browser dengan lebih terstruktur dan mudah dipahami. Hal ini juga membantu meningkatkan performa aplikasi dan memberikan pengalaman pengguna yang lebih baik. Mengapa Ini Penting untuk Developer? Dengan menggunakan fitur-fitur seperti class Response di Laravel, developer tidak hanya menghemat waktu tetapi juga memastikan aplikasi yang mereka bangun lebih terorganisir. Dalam dunia programming yang penuh tantangan, memiliki framework seperti Laravel yang mempermudah pengelolaan HTTP request dan response menjadi keuntungan besar. Framework ini memungkinkan developer untuk fokus pada coding yang benar-benar memberikan nilai tambah, alih-alih terjebak dalam detail teknis yang membosankan. Peran Class Response dalam HTTP Response Saat Membangun Proyek Website Ketika membangun sebuah proyek website, salah satu tugas utama yang harus dilakukan adalah mengelola HTTP response—yakni bagaimana server memberikan balasan kepada pengguna setelah menerima HTTP request dari browser. Dalam konteks ini, class Response di Laravel memainkan peran yang sangat penting. Class Response bertanggung jawab untuk memastikan bahwa setiap balasan yang dikirimkan dari server ke browser sesuai dengan format dan konten yang dibutuhkan. Balasan ini bisa berupa halaman HTML, file JSON untuk komunikasi API, file yang dapat di-download, atau bahkan pesan error ketika terjadi masalah di server. Sebagai contoh sederhana, bayangkan seorang pengguna meminta halaman profil mereka melalui browser. Class Response akan memastikan bahwa halaman yang dikirimkan kepada pengguna adalah halaman profil yang benar, dengan data yang sesuai, dan dalam format yang dapat dimengerti oleh browser. Selain itu, class Response juga memungkinkan developer untuk menambahkan elemen tambahan pada balasan, seperti header HTTP khusus atau pengaturan status kode HTTP (misalnya, 200 OK untuk sukses atau 404 Not Found untuk halaman yang tidak ditemukan). Hal ini membuat aplikasi lebih fleksibel dan dapat memberikan informasi yang lebih lengkap kepada pengguna maupun sistem lain yang berinteraksi dengan aplikasi. Dengan kata lain, class Response adalah jembatan utama antara server dan pengguna. Perannya sangat krusial untuk memastikan komunikasi antara keduanya berjalan lancar, cepat, dan sesuai harapan, baik dalam proyek kecil maupun aplikasi web skala besar. Contoh penggunaan Response pada website Berikut adalah beberapa contoh penggunaan class Response dalam proyek website toko mobil online menggunakan Laravel, dengan penjelasan dan contoh kode: Mengembalikan Halaman Daftar Mobil Ketika pengguna mengunjungi halaman daftar mobil, server harus mengirimkan halaman HTML yang berisi daftar mobil yang tersedia. use Illuminate\\Support\\Facades\\Response; public function showCarList() { $cars = Car::all(); return Response::view('cars.list', ['cars' => $cars], 200); } Penjelasan: Fungsi ini menggunakan Response::view() untuk mengirimkan halaman HTML (cars.list) dengan data mobil dari database. Mengirimkan Data Mobil dalam Format JSON Untuk aplikasi yang membutuhkan API, server bisa mengirimkan data mobil dalam format JSON. use Illuminate\\Support\\Facades\\Response; public function getCarData() { $cars = Car::all(); return Response::json(['data' => $cars], 200); } Penjelasan: Response::json() digunakan untuk mengirimkan response berupa data JSON yang sering digunakan dalam aplikasi modern. Memberikan File Invoice untuk Diunduh Ketika pengguna menyelesaikan pembelian, mereka dapat mengunduh file invoice. use Illuminate\\Support\\Facades\\Response; public function downloadInvoice($orderId) { $order = Order::findOrFail($orderId); $filePath = storage_path("invoices/{$order->invoice_file}"); return Response::download($filePath, "Invoice-{$order->id}.pdf"); } Penjelasan: Response::download() memungkinkan pengguna untuk mengunduh file invoice dari server. Mengirimkan Pesan Error untuk Halaman Tidak Ditemukan Jika pengguna mencoba mengakses halaman mobil yang tidak tersedia, server dapat mengirimkan response error. use Illuminate\\Support\\Facades\\Response; public function showCarDetails($id) { $car = Car::find($id); if (!$car) { return Response::make('Car not found', 404); } return Response::view('cars.details', ['car' => $car]); } Penjelasan: Response::make() digunakan untuk membuat pesan error dengan status kode tertentu, seperti 404 Not Found. Mengatur Custom Header pada Response Saat mengirimkan data atau halaman, server dapat menambahkan header khusus untuk kebutuhan keamanan atau debugging. use Illuminate\\Support\\Facades\\Response; public function getFeaturedCars() { $cars = Car::where('is_featured', true)->get(); return Response::json(['featured_cars' => $cars], 200) ->header('X-Featured-Cars-Count', $cars->count()); } Penjelasan: Dengan header(), kita bisa menambahkan header khusus seperti X-Featured-Cars-Count untuk memberikan informasi tambahan pada response. Setup HTTP Response dengan Status dan Konten Dalam aplikasi toko mobil online, pengaturan HTTP response yang jelas sangat penting untuk memberikan pengalaman pengguna yang baik. Contoh pengaturan response sederhana adalah ketika server ingin mengirimkan pesan teks dengan status HTTP tertentu. use Illuminate\\Support\\Facades\\Response; public function welcomeMessage() { return Response::make('Selamat datang di Toko Mobil Online!', 200) ->header('Content-Type', 'text/plain'); } Kode ini mengirimkan response berupa teks biasa dengan status 200 OK dan header Content-Type yang menunjukkan format teks biasa. Mengatur Header HTTP untuk Metadata Header HTTP sering digunakan untuk memberikan informasi tambahan, seperti metadata, pengaturan cache, atau informasi lain yang dibutuhkan oleh browser. use Illuminate\\Support\\Facades\\Response; public function carDetails($id) { $car = Car::find($id); if (!$car) { return Response::make('Mobil tidak ditemukan', 404) ->header('X-Error-Message', 'Mobil dengan ID tersebut tidak tersedia.'); } return Response::json($car) ->header('X-Car-Name', $car->name) ->header('Cache-Control', 'no-cache, must-revalidate'); } Kode ini menambahkan header khusus X-Car-Name dan Cache-Control untuk memberikan informasi tambahan kepada client, seperti nama mobil dan pengaturan cache. Mengirimkan Data dalam Format JSON Untuk aplikasi modern yang menggunakan API, JSON adalah format yang paling umum digunakan. Berikut contoh penggunaan class Response untuk mengirimkan data JSON: use Illuminate\\Support\\Facades\\Response; public function featuredCars() { $featuredCars = Car::where('is_featured', true)->get(); return Response::json([ 'status' => 'success', 'data' => $featuredCars, ], 200); } Kode ini mengirimkan data mobil unggulan dalam format JSON dengan status 200 OK, yang dapat digunakan oleh frontend atau aplikasi mobile. Mengunduh File Invoice Fitur file download sering digunakan pada aplikasi toko mobil online, misalnya untuk memberikan file invoice setelah pembelian berhasil. use Illuminate\\Support\\Facades\\Response; public function downloadInvoice($orderId) { $order = Order::findOrFail($orderId); $filePath = storage_path("invoices/{$order->invoice_file}"); return Response::download($filePath, "Invoice-Pesanan-{$order->id}.pdf"); } Kode ini memungkinkan pengguna untuk mengunduh file invoice yang telah di-generate oleh sistem. Streaming File Besar Untuk file yang berukuran besar, seperti dokumen atau katalog, fitur streaming membantu mengirimkan file secara efisien tanpa membebani server. use Illuminate\\Support\\Facades\\Response; public function streamCatalog() { $filePath = storage_path('catalogs/car-catalog.pdf'); return Response::stream(function () use ($filePath) { $stream = fopen($filePath, 'r'); fpassthru($stream); fclose($stream); }, 200, [ 'Content-Type' => 'application/pdf', 'Content-Disposition' => 'inline; filename="car-catalog.pdf"', ]); } Kode ini memungkinkan pengguna untuk melihat atau mengunduh file katalog mobil tanpa perlu menunggu file selesai diunduh sepenuhnya. Memberikan Response Kosong Terkadang, server hanya perlu memberikan response kosong dengan status HTTP tertentu, misalnya untuk operasi yang tidak memerlukan konten balasan. use Illuminate\\Support\\Facades\\Response; public function deleteCar($id) { $car = Car::find($id); if ($car) { $car->delete(); return Response::noContent(204); } return Response::make('Mobil tidak ditemukan', 404); } Kode ini mengirimkan status 204 No Content jika penghapusan berhasil dan 404 Not Found jika mobil tidak ditemukan. Membuat Response Custom Jika server perlu memberikan response yang unik dengan kombinasi konten dan header, Laravel mempermudah hal tersebut. use Illuminate\\Support\\Facades\\Response; public function customResponseExample() { return Response::make('Data berhasil diproses', 200) ->header('X-Custom-Header', 'LaravelResponseExample') ->header('Content-Type', 'text/plain'); } Kode ini menunjukkan bagaimana membuat response khusus dengan pesan, status, dan header custom sesuai kebutuhan. Setiap fitur ini menunjukkan kekuatan dan fleksibilitas class Response dalam Laravel, yang dapat membantu developer membangun aplikasi web yang lebih responsif, terstruktur, dan efisien. Beberapa Ksalahan Web Developer Pemula Ketika Menerapapakan Class Response Tidak Menyertakan Status Kode HTTP yang Tepat pada Response Salah satu kesalahan yang sering dilakukan oleh web developer pemula adalah tidak menyertakan status kode HTTP yang sesuai pada response. Status kode ini penting untuk memberikan informasi kepada client tentang hasil dari permintaan mereka, seperti apakah berhasil atau terjadi error. Kesalahan: use Illuminate\\Support\\Facades\\Response; public function getCarDetails($id) { $car = Car::find($id); if (!$car) { return Response::json(['message' => 'Car not found']); } return Response::json($car); } Pada kode di atas, jika data mobil tidak ditemukan, developer hanya mengembalikan pesan JSON tanpa menyertakan status kode HTTP seperti 404. Akibatnya, client tidak mendapatkan informasi yang jelas tentang error tersebut. Perbaikan: use Illuminate\\Support\\Facades\\Response; public function getCarDetails($id) { $car = Car::find($id); if (!$car) { return Response::json(['message' => 'Car not found'], 404); } return Response::json($car, 200); } Penjelasan: Dengan menambahkan status kode 404 untuk error dan 200 untuk keberhasilan, client dapat memahami hasil dari permintaan dengan lebih baik. Tidak Menggunakan Struktur JSON yang Konsisten Kesalahan lainnya adalah mengirimkan response JSON dengan struktur yang tidak konsisten. Ini menyulitkan client, terutama jika mereka harus menyesuaikan kode setiap kali response berubah. Kesalahan: use Illuminate\\Support\\Facades\\Response; public function getAllCars() { $cars = Car::all(); return Response::json($cars); } Kode di atas hanya mengembalikan data mentah dari database tanpa memberikan struktur tambahan, yang bisa membingungkan atau menyulitkan pengguna API. Perbaikan: use Illuminate\\Support\\Facades\\Response; public function getAllCars() { $cars = Car::all(); return Response::json([ 'status' => 'success', 'data' => $cars, ], 200); } Penjelasan: Dengan menambahkan struktur JSON yang konsisten, seperti properti status dan data, client dapat dengan mudah memahami format response tanpa harus menebak-nebak. Tidak Mengatur Header HTTP yang Penting Developer pemula sering lupa menambahkan header penting saat mengirimkan response, terutama ketika mengirim file atau data spesifik. Header seperti Content-Type membantu browser atau client memahami jenis data yang diterima. Kesalahan: use Illuminate\\Support\\Facades\\Response; public function downloadCatalog() { $filePath = storage_path('catalogs/car-catalog.pdf'); return Response::download($filePath); } Kode ini akan memungkinkan pengguna mengunduh file, tetapi tidak menyertakan header tambahan seperti Content-Disposition, yang dapat memberikan pengalaman unduhan yang lebih baik. Perbaikan: use Illuminate\\Support\\Facades\\Response; public function downloadCatalog() { $filePath = storage_path('catalogs/car-catalog.pdf'); return Response::download($filePath, 'car-catalog.pdf', [ 'Content-Type' => 'application/pdf', 'Content-Disposition' => 'attachment; filename="car-catalog.pdf"', ]); } Penjelasan: Dengan menambahkan header seperti Content-Type dan Content-Disposition, browser dapat mengenali file sebagai PDF dan menampilkan dialog unduhan dengan nama file yang benar. Ini meningkatkan pengalaman pengguna saat berinteraksi dengan aplikasi. Apaa Itu Redirect Response? Redirect response adalah salah satu fitur di Laravel yang memungkinkan developer mengarahkan pengguna dari satu URL ke URL lain. Redirect ini dapat digunakan untuk berbagai kebutuhan seperti setelah form submissaion, error handling, atau validasi. Laravel juga menyediakan cara mudah untuk melakukan redirect ke URL, named routes, atau bahkan controller actions. Redirect Response pada Proyek Website Toko Mobil Online Redirect Setelah Menambahkan Mobil Baru Setelah admin menambahkan mobil baru ke katalog, pengguna dapat diarahkan kembali ke halaman daftar mobil dengan pesan sukses. public function storeCar(Request $request) { $validated = $request->validate([ 'name' => 'required|string|max:255', 'price' => 'required|numeric', ]); Car::create($validated); return redirect()->route('cars.index')->with('success', 'Mobil berhasil ditambahkan ke katalog.'); } Penjelasan: Setelah data mobil berhasil disimpan, pengguna diarahkan ke named route cars.index dengan pesan flash berupa notifikasi sukses. Redirect ke Halaman Login Jika Belum Autentikasi Jika pengguna mencoba mengakses halaman dashboard tanpa login, mereka dapat diarahkan ke halaman login. public function dashboard() { if (!auth()->check()) { return redirect()->route('login')->with('error', 'Silakan login untuk mengakses dashboard.'); } return view('dashboard'); } Penjelasan: Jika pengguna tidak terautentikasi, mereka diarahkan ke halaman login dengan pesan flash berupa notifikasi error. Redirect Setelah Mengupdate Data Mobil Saat admin memperbarui data mobil, pengguna diarahkan kembali ke halaman detail mobil dengan pesan sukses. public function updateCar(Request $request, $id) { $car = Car::findOrFail($id); $validated = $request->validate([ 'name' => 'required|string|max:255', 'price' => 'required|numeric', ]); $car->update($validated); return redirect()->route('cars.show', $car->id)->with('success', 'Data mobil berhasil diperbarui.'); } Penjelasan: Fungsi ini mengarahkan pengguna ke halaman detail mobil (cars.show) setelah berhasil memperbarui data dengan menyertakan pesan sukses. Redirect Setelah Menghapus Mobil Ketika admin menghapus mobil dari katalog, pengguna diarahkan kembali ke halaman daftar mobil dengan pesan konfirmasi. public function deleteCar($id) { $car = Car::findOrFail($id); $car->delete(); return redirect()->route('cars.index')->with('success', 'Mobil berhasil dihapus dari katalog.'); } Penjelasan: Redirect digunakan untuk mengembalikan pengguna ke halaman daftar mobil (cars.index) setelah proses penghapusan selesai. Redirect dengan Data Flash Setelah Gagal Validasi Jika validasi form gagal, pengguna dapat diarahkan kembali ke halaman form sebelumnya dengan menyertakan pesan error dan data input yang sudah dimasukkan. public function storeCar(Request $request) { $validated = $request->validate([ 'name' => 'required|string|max:255', 'price' => 'required|numeric', ]); Car::create($validated); return redirect()->route('cars.index')->with('success', 'Mobil berhasil ditambahkan ke katalog.'); } public function storeCar(Request $request) { $validated = $request->validate([ 'name' => 'required|string|max:255', 'price' => 'required|numeric', ]); return redirect()->back()->withErrors($validated)->withInput(); } Penjelasan: Dengan menggunakan redirect()->back(), pengguna diarahkan kembali ke form dengan error message dan input sebelumnya, sehingga mereka tidak perlu mengisi ulang form dari awal. Redirecting to Controller Actions Redirect juga dapat dilakukan langsung ke metode dalam controller lain. Ini bermanfaat jika Anda ingin mengarahkan pengguna ke tindakan lain tanpa harus menentukan route. public function deleteCar($id) { $car = Car::findOrFail($id); $car->delete(); return redirect()->action([CarController::class, 'index'])->with('success', 'Mobil berhasil dihapus dari katalog.'); } Penjelasan: Dengan menggunakan redirect()->action(), pengguna diarahkan ke metode index dalam CarController, yang akan menampilkan daftar mobil. Ini lebih fleksibel jika ada perubahan pada nama route di masa depan. Dengan memahami dan memanfaatkan redirect response secara maksimal, Anda dapat menciptakan alur pengguna yang lebih baik pada website toko mobil online, meningkatkan pengalaman pengguna, dan mempermudah pengelolaan kode. Kesimpulan dan Saran Kesalahan dalam mengelola class Response di Laravel adalah hal yang wajar terjadi bagi web developer pemula. Mulai dari tidak menyertakan status kode HTTP yang tepat, struktur JSON yang tidak konsisten, hingga lupa menambahkan header penting, semuanya dapat diatasi dengan pembelajaran dan pengalaman yang terus berkembang. Framework seperti Laravel memberikan kemudahan dan fleksibilitas, tetapi memahami cara penggunaannya dengan benar adalah kunci untuk membangun aplikasi web yang profesional. Untuk web developer pemula yang ingin mempercepat proses belajar dan mempersiapkan karir di dunia web development, bergabung dengan mentor expert di BuildWithAngga bisa menjadi pilihan terbaik. Berikut adalah beberapa alasan mengapa belajar di BuildWithAngga sangat bermanfaat: Akses Seumur Hidup: Materi pembelajaran yang selalu bisa diakses kapan saja memberikan fleksibilitas bagi Anda untuk belajar sesuai ritme dan kebutuhan.Portfolio Berkualitas: Anda akan dipandu untuk membuat proyek nyata yang tidak hanya meningkatkan keterampilan, tetapi juga memperkuat portfolio, sebuah elemen penting untuk melamar pekerjaan atau mengambil proyek freelance.Konsultasi Karir: Kesempatan berkonsultasi langsung dengan mentor expert membantu Anda merencanakan langkah karir yang lebih strategis dan menjawab tantangan di dunia kerja. Dengan belajar bersama mentor yang berpengalaman di BuildWithAngga, Anda tidak hanya akan menguasai teknis pemrograman, tetapi juga siap menghadapi persaingan dunia kerja dengan bekal yang lebih matang. Mari tingkatkan potensi Anda dan wujudkan karir impian bersama BuildWithAngga!

Kelas Belajar Mengenal Class Request Pada Framework Laravel 11 di BuildWithAngga

Belajar Mengenal Class Request Pada Framework Laravel 11

Laravel adalah salah satu framework PHP yang dirancang untuk membuat proses web development menjadi lebih mudah dan menyenangkan bagi para developer. Fokus utama Laravel adalah memberikan pengalaman pengembang yang efisien dengan menyediakan struktur kode yang rapi, sintaks yang elegan, dan fitur-fitur canggih seperti routing, middleware, serta pengelolaan database yang intuitif. Framework ini sering dianggap sebagai "kerangka kerja yang ramah developer" karena menawarkan banyak alat bawaan untuk menyelesaikan tugas-tugas kompleks tanpa harus memulai semuanya dari nol. Salah satu fitur penting yang membantu mencapai tujuan ini adalah kelas Request. Apa Itu Request dalam Laravel? Dalam Laravel, kelas Request adalah alat penting yang berfungsi untuk menangani permintaan HTTP yang masuk ke aplikasi. Permintaan ini bisa berupa form yang dikirimkan pengguna, data yang diambil dari URL, atau informasi lainnya yang dikirim melalui browser. Bayangkan Anda memiliki sebuah restoran. Ketika pelanggan datang, mereka memberikan pesanan kepada pelayan. Pelayan ini bertugas mencatat pesanan tersebut, memastikan semua detailnya benar, dan menyampaikannya ke dapur untuk diproses. Dalam analogi ini: Pelanggan adalah pengguna aplikasi.Pesanan mereka adalah permintaan HTTP.Pelayan adalah kelas Request.Dapur adalah bagian logika aplikasi Anda yang akan memproses permintaan tersebut. Mengapa Request Penting? Kelas Request memungkinkan developer untuk memahami dan memproses apa yang sebenarnya diminta oleh pengguna dengan cara yang sistematis. Sama seperti pelayan di restoran yang memastikan pesanan pelanggan benar, kelas Request membantu memastikan data yang diterima oleh aplikasi Anda sesuai dengan kebutuhan, baik itu validasi input, sanitasi data, atau hanya mengambil informasi tertentu. Laravel memberikan fleksibilitas yang besar untuk bekerja dengan Request. Anda bisa mendapatkan data dari form, URL, atau bahkan mengakses file yang diunggah pengguna dengan sangat mudah. Selain itu, Request juga mendukung berbagai metode validasi bawaan untuk memastikan bahwa semua data yang diterima aman dan sesuai standar. Fungsi dan Struktur Kelas Request Kelas Request tidak hanya berguna untuk mendapatkan data dari pengguna, tetapi juga membantu menjaga keamanan aplikasi Anda. Misalnya, dengan memastikan bahwa data yang masuk tidak berbahaya atau mengandung elemen yang bisa merusak sistem. S ama seperti pelayan restoran yang tidak hanya menyampaikan pesanan tetapi juga memeriksa apakah pesanan itu masuk akal (misalnya, pelanggan tidak memesan sesuatu yang tidak ada di menu), Request memeriksa data sebelum dikirim ke logika bisnis Anda. Fitur Utama Pada Request Laravel menyediakan berbagai fitur melalui kelas Request untuk membantu developer menangani data dari permintaan HTTP dengan mudah. Berikut adalah beberapa fitur utamanya: Mengakses Data Permintaan Kelas Request memungkinkan Anda untuk mengambil data yang dikirim melalui metode GET atau POST. Data ini bisa diakses menggunakan berbagai metode seperti input(), query(), dan post(). use Illuminate\\Http\\Request; public function handleRequest(Request $request) { // Mengambil data dari input $name = $request->input('name'); // Mendapatkan nilai dari input 'name' $age = $request->query('age'); // Mendapatkan nilai dari query string 'age' $email = $request->post('email'); // Mendapatkan nilai dari POST 'email' return response()->json([ 'name' => $name, 'age' => $age, 'email' => $email, ]); } Bekerja dengan Header Header HTTP sering digunakan untuk informasi tambahan, seperti autentikasi atau jenis konten. Anda bisa mengambil nilai header menggunakan metode header(). use Illuminate\\Http\\Request; public function handleHeader(Request $request) { // Mengambil header Authorization $authHeader = $request->header('Authorization'); // Mengambil header Content-Type $contentType = $request->header('Content-Type'); return response()->json([ 'authorization' => $authHeader, 'content_type' => $contentType, ]); } Upload File Laravel menyediakan metode sederhana untuk menangani file yang diunggah pengguna. Anda bisa menggunakan metode file() untuk mengakses file dan store() atau storeAs() untuk menyimpannya. use Illuminate\\Http\\Request; public function handleFileUpload(Request $request) { // Mengambil file yang diunggah $uploadedFile = $request->file('document'); // Menyimpan file di folder 'uploads' $path = $uploadedFile->store('uploads'); return response()->json([ 'file_path' => $path, ]); } Metadata Permintaan Kelas Request juga memungkinkan Anda mengakses metadata tentang permintaan, seperti URL, metode HTTP, dan alamat IP. use Illuminate\\Http\\Request; public function handleMetadata(Request $request) { // Mengambil URL permintaan $url = $request->url(); // Mengambil metode permintaan (GET, POST, dll.) $method = $request->method(); // Mengambil alamat IP pengguna $ipAddress = $request->ip(); return response()->json([ 'url' => $url, 'method' => $method, 'ip_address' => $ipAddress, ]); } Dengan fitur-fitur di atas, kelas Request membantu developer menangani data permintaan dengan lebih fleksibel dan efisien. Memahami fitur ini akan sangat bermanfaat dalam mengembangkan aplikasi web yang aman dan fungsional. Dependency Injection pada Request Laravel secara otomatis menginjeksikan objek Request ke dalam metode controller ketika Anda mendefinisikan parameter tipe Request. Ini berarti Anda tidak perlu membuat atau menginisialisasi objek Request secara manual. Laravel secara cerdas mendeteksi kebutuhan ini dan menyediakan objek yang sesuai. Bayangkan di restoran, seorang pelayan secara otomatis tahu apa yang harus dilakukan dengan pesanan pelanggan tanpa Anda harus menginstruksikan setiap langkah. Laravel memainkan peran seperti ini, memastikan objek Request tersedia langsung saat dibutuhkan. Berikut contoh metode controller dengan dependency injection: use Illuminate\\Http\\Request; class OrderController extends Controller { public function submitOrder(Request $request) { // Mengambil data dari request $customerName = $request->input('customer_name'); $menuItem = $request->input('menu_item'); return response()->json([ 'message' => 'Order received', 'customer_name' => $customerName, 'menu_item' => $menuItem, ]); } } Ketika metode ini dipanggil, Laravel secara otomatis mengisi parameter $request dengan data permintaan yang sesuai. Anda cukup fokus pada logika bisnis, seperti mengambil atau memproses data. Validasi Input Menggunakan Kelas Request Laravel menyediakan metode bawaan untuk melakukan validasi input, memastikan data yang masuk ke aplikasi Anda sesuai dengan aturan tertentu. Proses ini menjaga aplikasi tetap aman dan mencegah kesalahan yang tidak diinginkan. Dalam analogi restoran, validasi ini seperti pelayan yang memeriksa apakah pesanan pelanggan sudah sesuai, misalnya, apakah item yang dipesan ada di menu atau apakah jumlahnya masuk akal. Jika ada kesalahan, pelayan akan memberi tahu pelanggan sebelum pesanan diteruskan ke dapur. Berikut adalah contoh validasi menggunakan metode bawaan $request->validate(): use Illuminate\\Http\\Request; class OrderController extends Controller { public function validateOrder(Request $request) { // Validasi input $validatedData = $request->validate([ 'customer_name' => 'required|string|max:255', 'menu_item' => 'required|string', 'quantity' => 'required|integer|min:1', ]); // Jika validasi berhasil, data aman untuk diproses return response()->json([ 'message' => 'Order is valid', 'data' => $validatedData, ]); } } Jika input tidak sesuai aturan validasi, Laravel secara otomatis akan mengembalikan respons error kepada pengguna, lengkap dengan pesan yang relevan. Dengan menggunakan fitur validasi bawaan, Laravel memastikan bahwa hanya data yang valid dan aman yang diteruskan ke logika aplikasi Anda. Ini mengurangi risiko kesalahan atau eksploitasi keamanan. Sama seperti pelayan restoran yang menjaga agar pesanan tidak mengandung elemen yang tidak diinginkan, kelas Request membantu aplikasi Anda tetap efisien dan aman. Penggunaan Lanjutan Kelas Request Laravel menyediakan fitur-fitur lanjutan dalam kelas Request untuk memodifikasi data input, memisahkan logika validasi ke dalam kelas khusus, dan memeriksa atribut dengan mudah. Fitur-fitur ini dirancang untuk meningkatkan fleksibilitas dan kemudahan pengelolaan data permintaan HTTP. Bayangkan sebuah restoran yang memiliki sistem canggih untuk memodifikasi pesanan pelanggan, memastikan pesanan sesuai dengan kebutuhan, dan memeriksa kelengkapan pesanan sebelum diteruskan ke dapur. Menggabungkan dan Mengganti Input Kadang-kadang, Anda perlu menambahkan data baru atau mengganti data input sebelum diproses lebih lanjut. Laravel menyediakan metode merge() dan replace() untuk menangani kebutuhan ini. Dalam analogi restoran, ini seperti pelayan yang menambahkan atau mengganti detail pesanan pelanggan, misalnya menambahkan catatan "tanpa garam" atau mengganti ukuran porsi dari "medium" ke "large". use Illuminate\\Http\\Request; class OrderController extends Controller { public function modifyOrder(Request $request) { // Menambahkan data baru ke input $request->merge(['special_note' => 'Extra cheese requested']); // Mengganti input yang ada $request->replace([ 'menu_item' => 'Pizza', 'quantity' => 2, 'special_note' => 'No onions', ]); return response()->json([ 'modified_data' => $request->all(), ]); } } Kelas Request Kustom Untuk memisahkan logika validasi dari controller, Anda dapat membuat kelas request kustom. Kelas ini memungkinkan Anda mendefinisikan aturan validasi, otorisasi, dan bahkan metode tambahan untuk membantu pengelolaan data. Ini seperti memiliki pelayan khusus yang bertanggung jawab memastikan semua pesanan pelanggan sesuai dengan standar restoran. // Membuat kelas request kustom php artisan make:request OrderRequest Isi dari OrderRequest.php: namespace App\\Http\\Requests; use Illuminate\\Foundation\\Http\\FormRequest; class OrderRequest extends FormRequest { public function authorize() { // Mengizinkan semua pengguna untuk melakukan permintaan ini return true; } public function rules() { // Aturan validasi untuk input return [ 'customer_name' => 'required|string|max:255', 'menu_item' => 'required|string', 'quantity' => 'required|integer|min:1', ]; } } Di dalam controller: use App\\Http\\Requests\\OrderRequest; class OrderController extends Controller { public function processOrder(OrderRequest $request) { // Data sudah tervalidasi di kelas request $data = $request->validated(); return response()->json([ 'message' => 'Order processed successfully', 'data' => $data, ]); } } Keuntungan menggunakan kelas request kustom adalah logika validasi terpisah dari controller, sehingga kode lebih bersih dan terorganisasi. Memeriksa Atribut Request Laravel menyediakan metode seperti has(), filled(), dan missing() untuk memeriksa apakah atribut tertentu ada, terisi, atau tidak ada. Dalam konteks restoran, ini seperti pelayan yang memeriksa apakah pelanggan sudah menentukan jumlah porsi atau apakah ada catatan khusus pada pesanan. use Illuminate\\Http\\Request; class OrderController extends Controller { public function checkAttributes(Request $request) { $hasMenuItem = $request->has('menu_item'); // Memeriksa apakah input 'menu_item' ada $isQuantityFilled = $request->filled('quantity'); // Memeriksa apakah input 'quantity' tidak kosong $isSpecialNoteMissing = $request->missing('special_note'); // Memeriksa apakah 'special_note' tidak ada return response()->json([ 'has_menu_item' => $hasMenuItem, 'is_quantity_filled' => $isQuantityFilled, 'is_special_note_missing' => $isSpecialNoteMissing, ]); } } Dengan fitur-fitur lanjutan seperti memodifikasi data input, memanfaatkan kelas request kustom, dan memeriksa atribut dengan mudah, Laravel memberikan fleksibilitas untuk menangani permintaan HTTP secara profesional. Sama seperti sistem restoran modern yang dirancang untuk mengelola pesanan dengan efisien, kelas Request mempermudah developer dalam mengelola data dengan cara yang bersih, aman, dan terstruktur. Kesalahan Umum dan Cara Menghindarinya Saat menggunakan kelas Request di Laravel, ada beberapa kesalahan umum yang sering dilakukan oleh pemula. Kesalahan ini dapat menyebabkan aplikasi tidak berjalan seperti yang diharapkan atau bahkan membuka celah keamanan. Dengan memahami kesalahan ini, Anda dapat menghindarinya dan memastikan aplikasi tetap aman dan fungsional. Bayangkan Anda memiliki restoran. Jika pelayan tidak memvalidasi pesanan pelanggan, salah memahami metode pemesanan, atau mengambil catatan pesanan dari sumber yang salah, pelanggan bisa saja mendapatkan pesanan yang salah atau bahkan tidak mendapatkan layanan sama sekali. Hal serupa dapat terjadi dalam aplikasi web jika Request tidak digunakan dengan benar. Tidak Memvalidasi Input Pengguna Kesalahan ini seperti menerima pesanan pelanggan tanpa memeriksa apakah pesanan itu benar atau sesuai menu restoran. Dalam aplikasi, jika input pengguna tidak divalidasi, ada risiko keamanan seperti SQL Injection, XSS, atau data yang tidak konsisten. Untuk menghindari hal ini, selalu validasi input pengguna menggunakan $request->validate() atau kelas request kustom. use Illuminate\\Http\\Request; class OrderController extends Controller { public function submitOrder(Request $request) { // Validasi input $validatedData = $request->validate([ 'customer_name' => 'required|string|max:255', 'menu_item' => 'required|string', 'quantity' => 'required|integer|min:1', ]); // Proses data yang sudah tervalidasi return response()->json([ 'message' => 'Order submitted successfully', 'data' => $validatedData, ]); } } Kesalahan ini dapat dihindari dengan memastikan semua input selalu divalidasi sebelum diproses lebih lanjut. Kesalahan dalam Memahami Metode Request Bayangkan seorang pelanggan ingin memesan makanan melalui panggilan telepon, tetapi pelayan malah mengharapkan mereka datang langsung ke restoran. Dalam aplikasi, kesalahan ini terjadi ketika Anda mengirim permintaan POST ke route yang hanya mendukung GET, atau sebaliknya. Akibatnya, server tidak dapat menangani permintaan tersebut. Misalnya, route hanya mendukung GET: Route::get('/order', [OrderController::class, 'viewOrder']); Tetapi permintaan dikirim menggunakan POST. Untuk menghindari kesalahan ini, pastikan metode permintaan sesuai dengan definisi route. Di controller, Anda dapat memeriksa metode permintaan menggunakan $request->method(): use Illuminate\\Http\\Request; class OrderController extends Controller { public function viewOrder(Request $request) { // Memastikan metode permintaan adalah GET if ($request->method() !== 'GET') { return response()->json([ 'error' => 'Invalid request method', ], 405); } return response()->json([ 'message' => 'Order viewed successfully', ]); } } Mengakses Sumber Data yang Salah Kesalahan ini seperti pelayan yang mencari pesanan pelanggan di meja yang salah. Dalam aplikasi, ini terjadi ketika Anda mencoba mengakses data GET menggunakan $request->post() atau data POST menggunakan $request->query(). Untuk menghindari kesalahan ini, gunakan metode yang benar sesuai sumber data. Berikut contoh yang benar: use Illuminate\\Http\\Request; class OrderController extends Controller { public function processOrder(Request $request) { // Mengambil data GET $menuItem = $request->query('menu_item'); // Mengambil data POST $quantity = $request->post('quantity'); // Pastikan data sesuai dengan sumbernya return response()->json([ 'menu_item' => $menuItem, 'quantity' => $quantity, ]); } } Jika Anda tidak yakin dengan sumber data, gunakan $request->input(), karena metode ini dapat mengambil data baik dari GET maupun POST. Kesalahan seperti tidak memvalidasi input, salah memahami metode request, atau mengakses sumber data yang salah bisa menyebabkan masalah serius dalam aplikasi web. Dengan memahami cara kerja Request dan selalu memvalidasi data, Anda dapat mencegah risiko ini. Sama seperti pelayan restoran yang memastikan setiap pesanan benar dan berasal dari pelanggan yang tepat, Anda perlu memastikan bahwa aplikasi Anda menangani permintaan HTTP dengan hati-hati dan aman. Beberapa Contoh Praktis Request Kelas Request di Laravel memberikan banyak kemudahan untuk menangani data dari formulir, file unggahan, dan parameter query string. Berikut beberapa contoh praktis penggunaannya, dilengkapi dengan analogi restoran untuk membantu pemahaman. Penanganan Formulir Sederhana Bayangkan restoran menerima pesanan dari pelanggan melalui formulir di kertas. Pelayan akan memastikan semua informasi di formulir lengkap dan benar sebelum memproses pesanan. Dalam Laravel, formulir kontak dapat ditangani dengan cara yang serupa, menggunakan kelas Request untuk memvalidasi data sebelum diproses. Contoh penanganan formulir kontak: use Illuminate\\Http\\Request; class ContactController extends Controller { public function submitContactForm(Request $request) { // Validasi input formulir $validatedData = $request->validate([ 'name' => 'required|string|max:255', 'email' => 'required|email|max:255', 'message' => 'required|string|min:10', ]); // Proses data (misalnya, menyimpan ke database atau mengirim email) return response()->json([ 'message' => 'Thank you for your message!', 'data' => $validatedData, ]); } } Di sini, validasi memastikan bahwa informasi seperti nama, email, dan pesan sudah lengkap dan sesuai sebelum diteruskan. Contoh Upload File Di restoran, pelanggan mungkin ingin memberikan catatan khusus dalam bentuk foto menu favorit atau sketsa meja. Pelayan akan menerima file ini dengan hati-hati dan menyimpannya di tempat yang aman. Dalam Laravel, proses unggah file dapat dilakukan dengan mudah menggunakan metode file() dan store(). Contoh penanganan unggahan file: use Illuminate\\Http\\Request; class FileUploadController extends Controller { public function uploadFile(Request $request) { // Validasi file yang diunggah $validatedData = $request->validate([ 'document' => 'required|file|mimes:pdf,jpg,png|max:2048', // Maksimal 2MB ]); // Simpan file ke folder 'uploads' $filePath = $request->file('document')->store('uploads'); return response()->json([ 'message' => 'File uploaded successfully!', 'file_path' => $filePath, ]); } } Validasi memastikan bahwa file yang diunggah sesuai jenis dan ukuran yang diizinkan sebelum disimpan. Parsing Query String Di restoran, pelanggan sering kali mengajukan pertanyaan seperti "Apakah Anda memiliki menu vegetarian?" atau "Apakah ada meja untuk dua orang?". Pelayan akan memeriksa daftar menu atau ketersediaan meja sesuai permintaan pelanggan. Dalam Laravel, query string digunakan untuk permintaan semacam ini, misalnya, fitur pencarian dalam aplikasi. Contoh menangani fitur pencarian menggunakan query string: use Illuminate\\Http\\Request; class SearchController extends Controller { public function searchMenu(Request $request) { // Mengambil parameter query $searchTerm = $request->query('q', ''); // 'q' adalah parameter query $category = $request->query('category', 'all'); // Simulasi pencarian (misalnya, mencari di database) $results = [ 'term' => $searchTerm, 'category' => $category, 'items' => [ 'Spaghetti Bolognese', 'Grilled Chicken Salad', 'Vegetarian Pizza', ], ]; return response()->json([ 'message' => 'Search results', 'data' => $results, ]); } } Query string seperti ?q=pizza&category=vegetarian memungkinkan pengguna mencari menu tertentu berdasarkan kata kunci dan kategori. Penanganan Data JSON dalam Kelas Request Dalam pengembangan aplikasi modern, permintaan sering kali dikirim dalam format JSON, terutama untuk aplikasi berbasis API. Laravel menyediakan cara mudah untuk menangani data JSON melalui kelas Request, memungkinkan Anda membaca dan memproses data dengan efisien. Bayangkan sebuah restoran yang menerima pesanan secara digital melalui tablet. Pesanan dikirim dalam format digital (JSON), dan pelayan harus bisa membaca detail pesanan tersebut dengan benar untuk memastikan semuanya sesuai sebelum diteruskan ke dapur. Dalam Laravel, Request berperan sebagai pelayan yang membaca data JSON ini dan menyampaikannya ke aplikasi Anda. Membaca Data JSON dengan $request->json() Jika aplikasi Anda menerima data dalam format JSON, Anda dapat menggunakan metode $request->json() untuk mengaksesnya. Data JSON ini diperlakukan seperti array asosiatif sehingga mudah diakses menggunakan kunci. Berikut adalah contoh penanganan data JSON: use Illuminate\\Http\\Request; class OrderController extends Controller { public function processJsonOrder(Request $request) { // Memastikan data JSON diterima dengan benar $data = $request->json()->all(); // Mengakses data individual dari JSON $customerName = $request->json('customer_name'); $menuItem = $request->json('menu_item'); $quantity = $request->json('quantity', 1); // Default ke 1 jika 'quantity' tidak ada // Simulasi memproses pesanan return response()->json([ 'message' => 'Order processed successfully', 'order_details' => [ 'customer_name' => $customerName, 'menu_item' => $menuItem, 'quantity' => $quantity, ], ]); } } Dalam contoh ini: $request->json()->all() digunakan untuk mengambil seluruh data JSON.$request->json('key') digunakan untuk mengambil nilai tertentu dari JSON berdasarkan kunci.Anda dapat menambahkan nilai default pada parameter kedua untuk menangani kasus di mana kunci tidak ada. Mengirim Data JSON dalam Permintaan Biasanya, permintaan JSON dikirim dari klien, seperti aplikasi frontend atau alat pengujian API seperti Postman. Berikut adalah contoh data JSON yang dikirim ke endpoint Laravel: { "customer_name": "John Doe", "menu_item": "Grilled Chicken Salad", "quantity": 2 } Endpoint Laravel akan membaca data ini dengan mudah menggunakan metode $request->json(). Validasi Data JSON Sama seperti data dari formulir biasa, data JSON juga harus divalidasi untuk memastikan keamanannya. Anda dapat menggunakan metode $request->validate() untuk melakukannya. use Illuminate\\Http\\Request; class OrderController extends Controller { public function validateJsonOrder(Request $request) { // Validasi data JSON $validatedData = $request->validate([ 'customer_name' => 'required|string|max:255', 'menu_item' => 'required|string', 'quantity' => 'required|integer|min:1', ]); // Proses data setelah validasi berhasil return response()->json([ 'message' => 'Order is valid and processed', 'data' => $validatedData, ]); } } Validasi memastikan bahwa setiap pesanan memiliki format yang benar, seperti nama pelanggan dan item menu wajib diisi, serta jumlah pesanan adalah angka positif. Menangani data JSON dalam Laravel seperti pelayan restoran yang menerima pesanan digital dari pelanggan: memastikan pesanan terbaca dengan jelas, lengkap, dan aman sebelum diproses lebih lanjut. Dengan metode seperti $request->json(), Laravel memberikan cara yang sederhana dan efisien untuk bekerja dengan data JSON, baik untuk membaca, memvalidasi, maupun memprosesnya. Hal ini sangat penting dalam aplikasi modern yang sering berinteraksi dengan API berbasis JSON. Throttling dan Rate Limiting dalam Laravel Laravel menyediakan mekanisme throttling dan rate limiting untuk membatasi jumlah permintaan yang dapat dilakukan oleh pengguna dalam jangka waktu tertentu. Hal ini penting untuk mencegah penyalahgunaan, seperti serangan brute force atau flood requests yang dapat membebani server Anda. Bayangkan di restoran, seorang pelanggan mencoba memesan terus-menerus tanpa memberi waktu kepada pelayan untuk memproses pesanan. Untuk menjaga layanan tetap berjalan lancar, restoran dapat memberlakukan aturan seperti "setiap pelanggan hanya boleh memesan maksimal lima kali dalam satu jam." Laravel melakukan hal serupa dengan membatasi jumlah permintaan yang dapat dilakukan oleh setiap pengguna dalam interval waktu tertentu. Implementasi Throttling Menggunakan Middleware Laravel menyediakan middleware bawaan bernama throttle yang memanfaatkan informasi dari kelas Request untuk membatasi jumlah permintaan. Middleware ini dapat diterapkan pada route untuk memastikan pengguna tidak mengirimkan permintaan melebihi batas tertentu. Berikut adalah contoh penggunaan throttling: use Illuminate\\Http\\Request; Route::middleware('throttle:5,1')->group(function () { Route::get('/menu', function (Request $request) { return response()->json([ 'message' => 'Welcome to the menu!', ]); }); }); Penjelasan: throttle:5,1 berarti pengguna hanya diizinkan untuk mengirim maksimal 5 permintaan dalam waktu 1 menit.Jika batas ini terlampaui, Laravel secara otomatis akan mengembalikan respons HTTP 429 (Too Many Requests). Penanganan Respons Ketika Batas Tercapai Saat pengguna melebihi batas permintaan, Laravel mengembalikan pesan error yang dapat dikustomisasi. Anda juga dapat memberikan informasi tambahan seperti waktu tunggu sebelum mereka bisa mengirimkan permintaan lagi. Route::middleware('throttle:5,1')->group(function () { Route::get('/menu', function (Request $request) { return response()->json([ 'message' => 'Welcome to the menu!', ]); }); }); // Customizing the throttling response use Illuminate\\Http\\Exceptions\\ThrottleRequestsException; App::resolving(ThrottleRequestsException::class, function ($exception) { return response()->json([ 'error' => 'Too many requests, please slow down!', 'retry_after' => $exception->getHeaders()['Retry-After'] ?? 'unknown', ], 429); }); Throttling Berdasarkan Atribut Permintaan Laravel memungkinkan Anda membuat aturan throttling khusus berdasarkan atribut tertentu dari kelas Request, seperti alamat IP atau pengguna yang sedang login. Misalnya, jika restoran ingin membatasi pesanan berdasarkan nomor meja, Laravel dapat menggunakan informasi ini untuk mengatur batas. Berikut adalah contoh throttling berbasis IP: use Illuminate\\Support\\Facades\\RateLimiter; RateLimiter::for('menu', function (Request $request) { return Limit::perMinute(5)->by($request->ip()); }); Route::middleware('throttle:menu')->group(function () { Route::get('/menu', function (Request $request) { return response()->json([ 'message' => 'Menu is accessible!', ]); }); }); Penjelasan: RateLimiter::for memungkinkan Anda menentukan aturan throttling kustom.Dalam contoh ini, batas ditentukan berdasarkan alamat IP pengguna. Throttling Berdasarkan Pengguna yang Login Untuk aplikasi dengan autentikasi, Anda dapat mengatur batas berdasarkan ID pengguna, bukan hanya alamat IP. Ini seperti membatasi pesanan berdasarkan identitas pelanggan tetap di restoran. RateLimiter::for('orders', function (Request $request) { return Limit::perMinute(10)->by(optional($request->user())->id ?: $request->ip()); }); Route::middleware('throttle:orders')->group(function () { Route::post('/order', function (Request $request) { return response()->json([ 'message' => 'Order submitted successfully!', ]); }); }); Penjelasan: optional($request->user())->id memastikan bahwa aturan berlaku untuk pengguna yang login.Jika pengguna tidak login, batasan berlaku berdasarkan alamat IP.aa Throttling dan rate limiting dalam Laravel membantu menjaga performa dan keamanan aplikasi Anda, seperti bagaimana restoran membatasi jumlah pesanan untuk menjaga efisiensi layanan. Dengan memanfaatkan informasi dari kelas Request, Anda dapat menetapkan aturan yang fleksibel dan kustom sesuai kebutuhan, memastikan bahwa setiap pengguna atau pelanggan mendapatkan layanan yang optimal tanpa mengganggu stabilitas sistem. Kelas Request dalam Jajaran Komponen Laravel Kelas Request adalah salah satu komponen penting dalam Laravel yang digunakan untuk menangani data permintaan HTTP. Kelas ini berinteraksi dengan berbagai komponen Laravel, termasuk route, controller, middleware, dan service container. Setiap komponen ini memiliki peran unik dalam memproses dan memanfaatkan data dari permintaan pengguna. Bayangkan sebuah restoran di mana pesanan pelanggan diterima oleh berbagai peran: Pelayan (route) menerima pesanan dan menyampaikan informasi awal.Dapur (controller) memproses pesanan menjadi makanan.Manajer dapur (middleware) memeriksa kelengkapan dan keamanan pesanan sebelum diproses.Sistem pemesanan pusat (service container) menyimpan data pesanan yang dapat diakses oleh seluruh tim. Laravel memiliki struktur serupa, di mana Request berperan sebagai alat komunikasi utama di antara komponen-komponen tersebut. Kelas Request di Route Pada level route, kelas Request digunakan untuk menangkap data awal yang dikirim pengguna. Route biasanya bertugas untuk menerima permintaan dan meneruskannya ke controller. use Illuminate\\Http\\Request; Route::post('/submit-order', function (Request $request) { $customerName = $request->input('customer_name'); $menuItem = $request->input('menu_item'); return response()->json([ 'message' => 'Order received', 'customer_name' => $customerName, 'menu_item' => $menuItem, ]); }); Analoginya, ini seperti pelayan restoran yang menerima pesanan langsung dari pelanggan dan mencatat detail awalnya. Kelas Request di Controller Controller adalah tempat utama untuk memproses data yang diterima dari Request. Data ini bisa divalidasi, diubah, atau diteruskan ke model untuk penyimpanan lebih lanjut. use Illuminate\\Http\\Request; class OrderController extends Controller { public function processOrder(Request $request) { // Validasi input $validatedData = $request->validate([ 'customer_name' => 'required|string|max:255', 'menu_item' => 'required|string', 'quantity' => 'required|integer|min:1', ]); // Simulasi pemrosesan pesanan return response()->json([ 'message' => 'Order processed successfully', 'order_details' => $validatedData, ]); } } Di restoran, ini seperti dapur yang memproses pesanan pelanggan menjadi makanan siap saji. Semua detail pesanan diperiksa terlebih dahulu untuk memastikan tidak ada kesalahan. Kelas Request di Middleware Middleware menggunakan Request untuk memeriksa atau memodifikasi permintaan sebelum diteruskan ke controller. Misalnya, middleware dapat memverifikasi autentikasi pengguna atau menambahkan atribut baru ke permintaan. namespace App\\Http\\Middleware; use Closure; use Illuminate\\Http\\Request; class EnsureCustomerIsAuthenticated { public function handle(Request $request, Closure $next) { if (!$request->has('auth_token')) { return response()->json([ 'error' => 'Unauthorized', ], 401); } return $next($request); } } Analoginya, ini seperti manajer dapur yang memeriksa apakah pelanggan sudah membayar sebelum pesanan diteruskan untuk diproses. Kelas Request di Service Container Service container memungkinkan Anda menggunakan kelas Request di seluruh aplikasi Laravel. Anda bisa menggunakannya untuk mengambil data permintaan di mana saja. use Illuminate\\Http\\Request; app()->bind('orderDetails', function (Request $request) { return [ 'customer_name' => $request->input('customer_name'), 'menu_item' => $request->input('menu_item'), ]; }); // Mengakses data dari service container $orderDetails = app('orderDetails'); return response()->json([ 'order_details' => $orderDetails, ]); Ini seperti sistem pemesanan pusat di restoran yang menyimpan data pesanan sehingga semua staf dapat mengaksesnya kapan saja.aa Penutup, Kesimpulan, dan Saran untuk Web Developer Pemula Laravel adalah framework yang dirancang untuk membuat web development menjadi lebih mudah dan terstruktur. Dengan fitur seperti kelas Request, Laravel memberikan alat yang powerful untuk menangani data permintaan HTTP, baik itu input formulir, file unggahan, atau query string. Seperti sebuah restoran dengan sistem manajemen yang terorganisasi, Laravel membantu developer memastikan semua data yang diterima aman, valid, dan siap untuk diproses lebih lanjut. Sebagai web developer pemula, perjalanan belajar Anda mungkin terasa penuh tantangan. Namun, dengan pendekatan yang tepat dan bimbingan yang baik, Anda dapat membangun aplikasi yang tidak hanya fungsional tetapi juga sesuai dengan standar industri. Salah satu langkah terbaik adalah belajar bersama mentor yang berpengalaman, seperti yang ditawarkan oleh BuildWithAngga. Mengapa Belajar di BuildWithAngga? BuildWithAngga memberikan program pembelajaran komprehensif yang dirancang untuk mempersiapkan Anda menjadi web developer profesional. Berikut adalah beberapa manfaat yang Anda dapatkan: Akses Materi Selamanya Tidak perlu khawatir tertinggal. Semua materi yang Anda pelajari dapat diakses kapan saja, sehingga Anda bisa belajar dengan tempo yang sesuai dengan kebutuhan Anda.Membangun Portfolio Profesional Anda akan diajarkan untuk membuat proyek-proyek nyata yang dapat digunakan sebagai portfolio. Portfolio ini akan menjadi kunci untuk membuka peluang kerja di perusahaan impian Anda.Konsultasi Karir dengan Mentor Berpengalaman Belajar langsung dari mentor yang telah sukses di industri. Anda juga bisa berdiskusi tentang karir, mendapatkan masukan tentang proyek, dan membangun relasi yang bermanfaat untuk masa depan.a Mempelajari Laravel dan web development secara keseluruhan bukan hanya tentang memahami kode, tetapi juga tentang bagaimana membangun aplikasi yang memenuhi kebutuhan pengguna dengan efisien dan aman. Dengan alat seperti kelas Request, Anda dapat menangani permintaan HTTP dengan mudah, memastikan validasi data, dan meningkatkan pengalaman pengguna. Jangan ragu untuk melangkah lebih jauh dalam karir web development Anda. Dengan belajar bersama BuildWithAngga, Anda tidak hanya mendapatkan ilmu tetapi juga dukungan penuh untuk mencapai tujuan karir Anda. Ayo mulai perjalanan Anda sekarang dan jadilah developer yang kompeten dan percaya diri! 🚀