Minggu, 28 Juni 2026

test

Hadits yang Anda maksud diriwayatkan oleh Imam al-Bukhari dan Imam Muslim dari Hakim bin Hizam radhiyallahu 'anhu.

Dengan harakat:

عَنْ حَكِيمِ بْنِ حِزَامٍ رَضِيَ اللَّهُ عَنْهُ، عَنِ النَّبِيِّ ﷺ قَالَ:

«الْبَيِّعَانِ بِالْخِيَارِ مَا لَمْ يَتَفَرَّقَا، فَإِنْ صَدَقَا وَبَيَّنَا بُورِكَ لَهُمَا فِي بَيْعِهِمَا، وَإِنْ كَذَبَا وَكَتَمَا مُحِقَتْ بَرَكَةُ بَيْعِهِمَا.»

Terjemah:

Dari Hakim bin Hizam radhiyallahu 'anhu, dari Nabi ﷺ, beliau bersabda:

"Penjual dan pembeli masih memiliki hak memilih (melanjutkan atau membatalkan transaksi) selama mereka belum berpisah. Jika keduanya jujur dan menjelaskan (keadaan barang dengan apa adanya), niscaya keduanya akan diberi keberkahan dalam jual beli mereka. Namun jika keduanya berdusta dan menyembunyikan (cacat barang), maka dihapuslah keberkahan jual beli mereka."

Referensi:

  • Shahih al-Bukhari, no. 2079.
  • Shahih Muslim, no. 1532.

Hadits ini menjadi salah satu dalil utama dalam Islam bahwa kejujuran dan keterbukaan dalam muamalah merupakan sebab turunnya keberkahan, sedangkan kebohongan dan menyembunyikan cacat barang dapat menghilangkan keberkahan meskipun transaksi tersebut secara lahiriah menghasilkan keuntungan.

Jumat, 19 Juni 2026

floating windows

Jika yang Anda maksud adalah tombol ⋮ (three dots) yang ketika diklik muncul kotak menu mengambang seperti WhatsApp, Telegram, atau aplikasi mobile banking, maka Bootstrap 5 sudah menyediakan komponen Dropdown yang sangat cocok.

1. Tampilan Three Dot Vertikal

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css" rel="stylesheet">

<div class="dropdown">

    <button class="btn btn-light border-0"
            data-bs-toggle="dropdown">

        <i class="bi bi-three-dots-vertical"></i>

    </button>

    <ul class="dropdown-menu dropdown-menu-end shadow">

        <li>
            <a class="dropdown-item" href="#">
                <i class="bi bi-pencil me-2"></i>
                Edit
            </a>
        </li>

        <li>
            <a class="dropdown-item" href="#">
                <i class="bi bi-printer me-2"></i>
                Cetak
            </a>
        </li>

        <li>
            <a class="dropdown-item" href="#">
                <i class="bi bi-whatsapp me-2"></i>
                Kirim WA
            </a>
        </li>

        <li><hr class="dropdown-divider"></li>

        <li>
            <a class="dropdown-item text-danger" href="#">
                <i class="bi bi-trash me-2"></i>
                Hapus
            </a>
        </li>

    </ul>

</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>

Hasilnya:

      ⋮
      │
 ┌─────────────┐
 │ ✏ Edit      │
 │ 🖨 Cetak     │
 │ 📱 Kirim WA  │
 ├─────────────┤
 │ 🗑 Hapus     │
 └─────────────┘

2. Versi Lebih Elegan (Rounded & Floating)

Tambahkan CSS:

.dropdown-menu{
    border:none;
    border-radius:18px;
    padding:10px;
    min-width:220px;
    box-shadow:0 10px 30px rgba(0,0,0,.15);
}

.dropdown-item{
    border-radius:12px;
    padding:10px 14px;
}

.dropdown-item:hover{
    background:#f5f7fa;
}

Tampilannya mirip aplikasi mobile modern.


3. Floating Menu di Kartu Siswa

Contoh pada kartu siswa:

<div class="card shadow-sm rounded-4">

    <div class="card-body">

        <div class="d-flex justify-content-between">

            <div>
                <h5 class="mb-0">Ahmad Fauzan</h5>
                <small class="text-muted">
                    Tahsin A
                </small>
            </div>

            <div class="dropdown">

                <button
                    class="btn btn-light rounded-circle"
                    data-bs-toggle="dropdown">

                    <i class="bi bi-three-dots-vertical"></i>

                </button>

                <ul class="dropdown-menu dropdown-menu-end">

                    <li>
                        <a class="dropdown-item" href="#">
                            Detail
                        </a>
                    </li>

                    <li>
                        <a class="dropdown-item" href="#">
                            Edit
                        </a>
                    </li>

                    <li>
                        <a class="dropdown-item" href="#">
                            Kartu SPP
                        </a>
                    </li>

                    <li>
                        <a class="dropdown-item" href="#">
                            Pembayaran
                        </a>
                    </li>

                </ul>

            </div>

        </div>

    </div>

</div>

4. Floating Action Menu (Seperti Android)

Jika ingin benar-benar mengambang di kanan bawah layar:

<div class="dropup position-fixed bottom-0 end-0 m-4">

    <button class="btn btn-primary rounded-circle shadow"
            style="width:60px;height:60px"
            data-bs-toggle="dropdown">

        <i class="bi bi-three-dots fs-4"></i>

    </button>

    <ul class="dropdown-menu dropdown-menu-end shadow">

        <li><a class="dropdown-item" href="#">Tambah Siswa</a></li>
        <li><a class="dropdown-item" href="#">Tagihan Baru</a></li>
        <li><a class="dropdown-item" href="#">Laporan</a></li>

    </ul>

</div>

Tampilannya:

                   ┌──────────┐
                   │ Tambah   │
                   │ Tagihan  │
                   │ Laporan  │
                   └──────────┘

                        ●

Untuk aplikasi TPA/Bimbel yang sedang Anda buat, saya sarankan menggunakan Dropdown Bootstrap dengan dropdown-menu-end dan sudut membulat (rounded-4). Model ini paling mirip aplikasi profesional seperti Dana, BSI Mobile, atau MyTelkomsel, ringan, dan tidak perlu JavaScript tambahan selain Bootstrap.

Rabu, 17 Juni 2026

tampilkan pilihan

Masalahnya ada pada kondisi ini:

if($_GET['page']=='dataSiswa' or 'siswaNonAktif')

Bagian:

or 'siswaNonAktif'

selalu dianggap TRUE oleh PHP, sehingga kondisi menjadi tidak benar sesuai yang Anda inginkan.

Gunakan seperti ini:

<?php
if($_GET['page']=='dataSiswa' || $_GET['page']=='siswaNonAktif'){
?>
    <i class="bi bi-people text-primary"></i>
<?php
}else{
?>
    <i class="bi bi-people"></i>
<?php
}
?>

Atau yang lebih rapi:

<i class="bi bi-people <?=(isset($_GET['page']) && ($_GET['page']=='dataSiswa' || $_GET['page']=='siswaNonAktif')) ? 'text-primary' : '';?>"></i>

Sehingga menu Siswa akan berwarna biru ketika:

?page=dataSiswa

atau

?page=siswaNonAktif

Versi yang lebih aman

Untuk menghindari warning ketika $_GET['page'] belum ada:

<?php
$page = $_GET['page'] ?? '';

if(in_array($page,['dataSiswa','siswaNonAktif'])){
    echo '<i class="bi bi-people text-primary"></i>';
}else{
    echo '<i class="bi bi-people"></i>';
}
?>

Cara in_array() sangat cocok jika nanti submenu bertambah, misalnya:

in_array($page,[
    'dataSiswa',
    'siswaNonAktif',
    'siswaPindah',
    'siswaLulus'
])

jadi semua halaman yang berkaitan dengan siswa otomatis membuat ikon menu Siswa berwarna biru.

Minggu, 14 Juni 2026

Tanggal dengan rentang waktu tanpa submot

Bisa. Bahkan ini sangat umum digunakan pada dashboard laporan keuangan.

Caranya adalah membuat 2 input tanggal:

<div class="row">
    <div class="col-6">
        <input type="date" id="tgl_awal" class="form-control">
    </div>

    <div class="col-6">
        <input type="date" id="tgl_akhir" class="form-control">
    </div>
</div>

<div id="hasil"></div>

Javascript (Tanpa Submit)

Setiap kali salah satu tanggal berubah, data langsung diambil.

<script>

function loadData(){

    let awal  = document.getElementById('tgl_awal').value;
    let akhir = document.getElementById('tgl_akhir').value;

    if(awal && akhir){

        fetch(`laporan.php?awal=${awal}&akhir=${akhir}`)
        .then(response => response.text())
        .then(data => {

            document.getElementById('hasil').innerHTML = data;

        });

    }

}

document.getElementById('tgl_awal')
.addEventListener('change', loadData);

document.getElementById('tgl_akhir')
.addEventListener('change', loadData);

</script>

PHP

Misal file laporan.php

<?php

include 'koneksi.php';

$awal  = $_GET['awal'];
$akhir = $_GET['akhir'];

$query = mysqli_query($koneksi,"
SELECT *
FROM pembayaran
WHERE tanggal BETWEEN '$awal' AND '$akhir'
ORDER BY tanggal
");

while($row=mysqli_fetch_assoc($query)){

    echo "<div>";
    echo $row['tanggal']." - ";
    echo $row['nama']." - ";
    echo number_format($row['jumlah']);
    echo "</div>";

}

Untuk Dashboard Ringkasan

Misal Anda ingin otomatis mengubah:

  • Total pemasukan
  • Jumlah transaksi
  • Total tunggakan

Gunakan JSON.

PHP

<?php

include 'koneksi.php';

$awal  = $_GET['awal'];
$akhir = $_GET['akhir'];

$q = mysqli_query($koneksi,"
SELECT
SUM(jumlah) total,
COUNT(*) transaksi
FROM pembayaran
WHERE tanggal BETWEEN '$awal' AND '$akhir'
");

$data = mysqli_fetch_assoc($q);

echo json_encode($data);

Javascript

function loadData(){

    let awal  = $('#tgl_awal').val();
    let akhir = $('#tgl_akhir').val();

    if(awal && akhir){

        fetch(`summary.php?awal=${awal}&akhir=${akhir}`)
        .then(res => res.json())
        .then(data => {

            $('#total').html(
                'Rp ' + Number(data.total).toLocaleString('id-ID')
            );

            $('#transaksi').html(
                data.transaksi
            );

        });

    }
}

Lebih Elegan Lagi: Date Range Picker

Daripada dua input tanggal, gunakan satu input seperti:

01/06/2026 - 30/06/2026

Contohnya:

<input type="text" id="daterange" class="form-control">

Menggunakan plugin:

  • Date Range Picker
  • Flatpickr
  • Litepicker

Tampilannya seperti aplikasi kasir profesional dan laporan keuangan modern.

Contoh:

┌─────────────────────────┐
│ 📅 01 Jun - 30 Jun 2026 │
└─────────────────────────┘

Begitu rentang tanggal dipilih, AJAX langsung memuat ulang:

  • Ringkasan pemasukan
  • Grafik
  • Daftar pembayaran
  • Jumlah siswa yang membayar

tanpa tombol submit dan tanpa reload halaman. Ini adalah pola yang paling cocok untuk dashboard TPA/Bimbel yang sedang Anda bangun.

ganti data otomatis tanpa submit

Cara yang Anda inginkan adalah menggunakan AJAX atau Fetch API. Jadi ketika user mengganti tanggal pada <input type="date">, JavaScript langsung mengirim request ke PHP dan memperbarui data tanpa reload halaman dan tanpa tombol submit.

Contoh Sederhana

HTML

<input type="date" id="tanggal" class="form-control">

<div id="hasil">
    Silakan pilih tanggal
</div>

Javascript

<script>
document.getElementById('tanggal').addEventListener('change', function(){

    let tanggal = this.value;

    fetch('ambil_data.php?tanggal=' + tanggal)
    .then(response => response.text())
    .then(data => {

        document.getElementById('hasil').innerHTML = data;

    });

});
</script>

Ketika tanggal berubah, browser akan otomatis memanggil:

ambil_data.php?tanggal=2026-06-14

PHP (ambil_data.php)

<?php

$tanggal = $_GET['tanggal'];

include 'koneksi.php';

$query = mysqli_query($koneksi,"
SELECT *
FROM pembayaran
WHERE tanggal='$tanggal'
");

while($row = mysqli_fetch_assoc($query)){

    echo "<div>";
    echo $row['nama'];
    echo " - ";
    echo $row['jumlah'];
    echo "</div>";

}

Jika Menggunakan Bootstrap Card

Misal Anda punya ringkasan:

<div class="card">
    <div class="card-body">

        <h5>Total Pemasukan</h5>

        <h2 id="pemasukan">
            Rp0
        </h2>

    </div>
</div>

Javascript:

document.getElementById('tanggal').addEventListener('change', function(){

    let tanggal = this.value;

    fetch('summary.php?tanggal='+tanggal)
    .then(response => response.json())
    .then(data => {

        document.getElementById('pemasukan').innerHTML =
            'Rp' + Number(data.total).toLocaleString('id-ID');

    });

});

PHP:

<?php

$tanggal = $_GET['tanggal'];

include 'koneksi.php';

$q = mysqli_query($koneksi,"
SELECT SUM(jumlah) as total
FROM pembayaran
WHERE tanggal='$tanggal'
");

$data = mysqli_fetch_assoc($q);

echo json_encode($data);

Lebih Praktis dengan jQuery

Jika sudah menggunakan jQuery:

$('#tanggal').change(function(){

    let tanggal = $(this).val();

    $('#hasil').load(
        'ambil_data.php?tanggal='+tanggal
    );

});

Sangat singkat dan banyak dipakai di aplikasi admin.


Yang Paling Cocok Untuk Dashboard TPA Anda

Pada dashboard yang Anda buat:

  • User memilih tanggal.
  • Event change() terpanggil.
  • AJAX mengambil data:
    • Total pemasukan
    • Jumlah transaksi
    • Belum bayar
    • Daftar pembayaran
  • Card-card dashboard diperbarui otomatis.
  • Tidak ada tombol submit.
  • Tidak ada reload halaman.

Hasilnya terasa seperti aplikasi Android native meskipun hanya menggunakan PHP + Bootstrap 5.

Minggu, 07 Juni 2026

perbaikan

Pada script Anda sebenarnya sudah hampir benar. Yang perlu ditambahkan adalah:

  1. Preview foto harus memiliki id.
  2. Saat file dipilih, tampilkan preview.
  3. Upload otomatis menggunakan AJAX.
  4. Simpan path gambar ke database.
  5. Tidak perlu tombol upload.

1. Ubah bagian foto menjadi:

<div class="profile-wrapper">

    <img src="<?=$row['gambar'];?>"
         id="preview"
         class="profile-photo">

    <button type="button"
            class="camera-btn"
            onclick="document.getElementById('foto').click()">

        <i class="bi bi-camera-fill"></i>

    </button>

    <input type="file"
           id="foto"
           name="foto"
           accept="image/*"
           style="display:none;">

    <input type="hidden"
           id="id_siswa"
           value="<?=$idSiswa;?>">

</div>

<div id="uploadStatus"
     class="small mt-2 text-secondary">
</div>

2. Tambahkan script sebelum </body>

<script>

$('#foto').on('change', function(){

    let file = this.files[0];

    if(!file){
        return;
    }

    /*
    |--------------------------------------------------------------------------
    | Preview Langsung
    |--------------------------------------------------------------------------
    */
    let previewUrl = URL.createObjectURL(file);

    $('#preview').attr('src', previewUrl);

    $('#uploadStatus').html(
        '<span class="text-primary">Mengupload foto...</span>'
    );

    /*
    |--------------------------------------------------------------------------
    | Upload Otomatis
    |--------------------------------------------------------------------------
    */
    let formData = new FormData();

    formData.append('foto', file);
    formData.append(
        'id_siswa',
        $('#id_siswa').val()
    );

    $.ajax({

        url:'upload_foto_siswa.php',

        type:'POST',

        data:formData,

        contentType:false,

        processData:false,

        success:function(res){

            try{

                let data = JSON.parse(res);

                if(data.success){

                    $('#preview').attr(
                        'src',
                        data.url + '?t=' + Date.now()
                    );

                    $('#uploadStatus').html(
                        '<span class="text-success">✓ Foto berhasil diperbarui</span>'
                    );

                }else{

                    $('#uploadStatus').html(
                        '<span class="text-danger">Upload gagal</span>'
                    );

                }

            }catch(e){

                $('#uploadStatus').html(
                    '<span class="text-danger">Terjadi kesalahan</span>'
                );

            }

        }

    });

});

</script>

3. Buat file upload_foto_siswa.php

<?php

include "koneksi.php";

$response = [
    'success' => false
];

if(
    isset($_FILES['foto']) &&
    isset($_POST['id_siswa'])
){

    $id_siswa = $_POST['id_siswa'];

    $folder = "uploads/siswa/";

    if(!is_dir($folder)){
        mkdir($folder,0777,true);
    }

    $ext = strtolower(
        pathinfo(
            $_FILES['foto']['name'],
            PATHINFO_EXTENSION
        )
    );

    $namaFile =
        "siswa_" .
        $id_siswa .
        "_" .
        time() .
        "." .
        $ext;

    $path = $folder . $namaFile;

    if(
        move_uploaded_file(
            $_FILES['foto']['tmp_name'],
            $path
        )
    ){

        mysqli_query(
            $conn,
            "UPDATE tbl_siswa
             SET gambar='$path'
             WHERE id='$id_siswa'"
        );

        $response['success'] = true;
        $response['url'] = $path;

    }

}

echo json_encode($response);

Bonus (lebih elegan)

Tambahkan CSS berikut:

.camera-btn{
    position:absolute;
    right:5px;
    bottom:5px;
    width:42px;
    height:42px;
    border:none;
    border-radius:50%;
    background:#0d6efd;
    color:#fff;
    box-shadow:0 4px 10px rgba(0,0,0,.2);
}

.profile-wrapper{
    position:relative;
    width:140px;
    margin:auto;
}

Hasilnya akan seperti WhatsApp/Instagram:

  • Klik ikon kamera 📷
  • Pilih foto
  • Preview langsung berubah
  • Upload otomatis ke server
  • Database tbl_siswa.gambar langsung terupdate
  • Tidak ada tombol upload lagi.

upload otomatis

Bisa. Cara yang umum dipakai di aplikasi modern adalah auto upload setelah pengguna memilih file, tanpa tombol "Upload".

Misalnya Anda punya input:

<input type="file" id="foto" accept="image/*">

Lalu ketika file dipilih, JavaScript langsung mengirimkannya ke server.

HTML

<form id="formFoto" enctype="multipart/form-data">

    <input type="file"
           id="foto"
           name="foto"
           accept="image/*"
           hidden>

</form>

<button class="btn btn-primary"
        onclick="document.getElementById('foto').click()">
    <i class="bi bi-camera"></i>
    Ganti Foto
</button>

Javascript Auto Upload

document.getElementById('foto')
.addEventListener('change', function(){

    let file = this.files[0];

    if(!file) return;

    let formData = new FormData();
    formData.append('foto', file);

    fetch('upload-foto.php', {
        method: 'POST',
        body: formData
    })
    .then(response => response.json())
    .then(data => {

        if(data.success){

            alert('Foto berhasil diupload');

            // Update preview foto
            document.getElementById('fotoProfil').src =
                data.url + '?t=' + Date.now();

        }

    });

});

PHP Upload

<?php

$response = [
    'success' => false
];

if(isset($_FILES['foto'])){

    $namaFile = time() . '_' . $_FILES['foto']['name'];

    move_uploaded_file(
        $_FILES['foto']['tmp_name'],
        'uploads/' . $namaFile
    );

    $response['success'] = true;
    $response['url'] = 'uploads/' . $namaFile;
}

echo json_encode($response);

Preview Sebelum Upload

Kalau ingin seperti Instagram atau WhatsApp:

document.getElementById('foto')
.addEventListener('change', function(){

    let file = this.files[0];

    if(file){

        let url = URL.createObjectURL(file);

        document.getElementById('fotoProfil').src = url;

        uploadFoto(file);

    }

});

Dengan cara ini:

  1. Klik foto profil 📷
  2. Pilih gambar dari galeri
  3. Preview langsung berubah
  4. File langsung terupload ke server
  5. Tidak perlu tombol Upload

Untuk Smartphone (Rekomendasi)

Jika ingin saat diklik langsung membuka kamera HP:

<input type="file"
       id="foto"
       accept="image/*"
       capture="environment"
       hidden>

atau

<input type="file"
       id="foto"
       accept="image/*"
       capture="user"
       hidden>
  • capture="user" → kamera depan (selfie)
  • capture="environment" → kamera belakang

Kombinasi yang sering dipakai aplikasi modern adalah:

<input type="file"
       id="foto"
       accept="image/*"
       hidden>

Lalu tampilkan modal:

📷 Ambil Foto
🖼️ Pilih dari Galeri
🗑️ Hapus Foto

Sehingga pengalaman pengguna terasa seperti WhatsApp atau Instagram.

upload gambar

Berikut contoh lengkap menggunakan Bootstrap 5 + PHP, dimana:

✅ Klik foto profil
✅ Pilih gambar dari galeri
✅ Preview langsung berubah
✅ File langsung terupload otomatis
✅ Tidak perlu tombol Upload
✅ Mobile Friendly


1. index.php

<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

<title>Upload Foto Profil</title>

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" rel="stylesheet">

<style>

body{
    background:#f5f7fb;
}

.profile-container{
    max-width:400px;
    margin:50px auto;
}

.profile-card{
    background:white;
    border-radius:20px;
    padding:30px;
    text-align:center;
    box-shadow:0 5px 20px rgba(0,0,0,.08);
}

.profile-wrapper{
    position:relative;
    width:150px;
    margin:auto;
}

.profile-image{
    width:150px;
    height:150px;
    border-radius:50%;
    object-fit:cover;
    border:4px solid #fff;
    box-shadow:0 5px 15px rgba(0,0,0,.15);
}

.camera-btn{
    position:absolute;
    right:0;
    bottom:5px;

    width:45px;
    height:45px;

    border:none;
    border-radius:50%;

    background:#0d6efd;
    color:white;

    display:flex;
    align-items:center;
    justify-content:center;

    box-shadow:0 3px 10px rgba(0,0,0,.2);
}

.upload-status{
    margin-top:15px;
    font-size:14px;
}

</style>
</head>
<body>

<div class="container">

    <div class="profile-container">

        <div class="profile-card">

            <h3 class="mb-4">
                Foto Profil
            </h3>

            <div class="profile-wrapper">

                <img
                    id="preview"
                    src="uploads/default.png"
                    class="profile-image">

                <button
                    class="camera-btn"
                    onclick="pilihFoto()">

                    <i class="bi bi-camera-fill"></i>

                </button>

            </div>

            <h4 class="mt-4">
                Evander
            </h4>

            <p class="text-muted">
                Bimbel SMP
            </p>

            <div
                id="status"
                class="upload-status text-secondary">

                Klik ikon kamera untuk mengganti foto

            </div>

        </div>

    </div>

</div>

<input
    type="file"
    id="foto"
    accept="image/*"
    hidden>

<script>

function pilihFoto()
{
    document.getElementById('foto').click();
}

document
.getElementById('foto')
.addEventListener('change', function(){

    let file = this.files[0];

    if(!file)
    {
        return;
    }

    // Preview langsung

    let previewUrl = URL.createObjectURL(file);

    document
        .getElementById('preview')
        .src = previewUrl;

    document
        .getElementById('status')
        .innerHTML = 'Mengupload foto...';

    // Upload otomatis

    let formData = new FormData();

    formData.append('foto', file);

    fetch('upload.php', {

        method:'POST',
        body:formData

    })
    .then(response => response.json())

    .then(data => {

        if(data.success)
        {
            document
                .getElementById('status')
                .innerHTML =
                '<span class="text-success">✓ Foto berhasil diupload</span>';

            document
                .getElementById('preview')
                .src =
                data.url + '?v=' + Date.now();
        }
        else
        {
            document
                .getElementById('status')
                .innerHTML =
                '<span class="text-danger">Upload gagal</span>';
        }

    })
    .catch(error => {

        document
            .getElementById('status')
            .innerHTML =
            '<span class="text-danger">Terjadi kesalahan</span>';

    });

});

</script>

</body>
</html>

2. upload.php

<?php

header('Content-Type: application/json');

$response = [
    'success' => false
];

if(isset($_FILES['foto']))
{
    $folder = 'uploads/';

    if(!is_dir($folder))
    {
        mkdir($folder, 0777, true);
    }

    $ext = pathinfo(
        $_FILES['foto']['name'],
        PATHINFO_EXTENSION
    );

    $namaFile =
        'foto_' .
        time() .
        '.' .
        $ext;

    $tujuan = $folder . $namaFile;

    if(
        move_uploaded_file(
            $_FILES['foto']['tmp_name'],
            $tujuan
        )
    )
    {
        $response['success'] = true;
        $response['url'] = $tujuan;
    }
}

echo json_encode($response);

Struktur Folder

project/
│
├── index.php
├── upload.php
│
└── uploads/
     └── default.png

Jika Ingin Langsung Membuka Kamera HP

Ganti:

<input
    type="file"
    id="foto"
    accept="image/*"
    hidden>

menjadi:

<input
    type="file"
    id="foto"
    accept="image/*"
    capture="user"
    hidden>

Maka pada sebagian besar smartphone Android:

📷 Klik ikon kamera → Kamera depan langsung terbuka → Ambil foto → Upload otomatis → Preview berubah otomatis.

Ini adalah pola yang mirip dengan aplikasi WhatsApp dan Instagram saat mengganti foto profil.

Sabtu, 06 Juni 2026

ambil gbar

Di browser, Anda tidak bisa langsung memaksa membuka kamera hanya dengan tag <a>. Yang umum dilakukan adalah menggunakan <input type="file"> dengan atribut:

accept="image/*"
capture="environment"

Kemudian saat menu "Ambil Foto" diklik, trigger input tersebut.

HTML

<a href="#"
   class="list-group-item list-group-item-action"
   onclick="document.getElementById('cameraInput').click(); return false;">
    
    <i class="bi bi-camera me-2"></i>
    Ambil Foto

</a>

<input type="file"
       id="cameraInput"
       accept="image/*"
       capture="environment"
       style="display:none;">

Preview Hasil Foto

Tambahkan elemen gambar:

<img id="previewFoto"
     src="<?=$row['gambar']?>"
     class="profile-photo">

Lalu JavaScript:

<script>
document.getElementById('cameraInput')
.addEventListener('change', function(e){

    const file = e.target.files[0];

    if(file){
        document.getElementById('previewFoto').src =
            URL.createObjectURL(file);
    }

});
</script>

Kamera Belakang atau Depan

Kamera belakang (default Android):

capture="environment"

Kamera depan (selfie):

capture="user"

Catatan Penting

Perilakunya tergantung perangkat:

  • Android Chrome → biasanya langsung muncul pilihan Kamera atau Galeri.
  • Beberapa Android → langsung membuka kamera.
  • iPhone Safari → biasanya menampilkan pilihan:
    • Take Photo
    • Photo Library

Ini normal dan tidak bisa dipaksa 100% oleh browser.


Jika Ingin Benar-Benar Mirip WhatsApp/Instagram

Gunakan API kamera browser:

navigator.mediaDevices.getUserMedia()

yang akan membuka kamera langsung di dalam modal Bootstrap dan menampilkan preview live. Setelah pengguna menekan tombol, foto diambil dan langsung di-upload. Ini terlihat jauh lebih profesional dan modern daripada input file biasa.

Untuk aplikasi bimbel Gardenia 1, saya merekomendasikan pendekatan kedua (kamera live dalam modal) karena pengalaman pengguna jauh lebih baik.

update foto

Untuk halaman update foto profil siswa, saya sarankan jangan hanya menampilkan foto bulat dan tombol upload biasa. Buatlah seperti pengalaman di Instagram, WhatsApp, atau Facebook agar terasa modern dan premium.

Contoh layout yang elegan:

┌────────────────────────────┐
│      Foto Profil           │
│                            │
│        ( FOTO )            │
│           📷               │
│                            │
│       Evander              │
│       Bimbel SMP           │
│                            │
│ [ Pilih Foto Baru ]        │
│                            │
│ Drag & Drop atau klik      │
│                            │
│  Preview Foto Baru         │
│                            │
│ [ Batal ] [ Simpan ]       │
└────────────────────────────┘

Desain ala Media Sosial

Foto profil diberi tombol kamera mengambang di kanan bawah.

<div class="profile-wrapper">
    
    <img src="foto.jpg" class="profile-image">

    <button class="camera-btn">
        <i class="bi bi-camera-fill"></i>
    </button>

</div>

CSS:

.profile-wrapper{
    position:relative;
    width:140px;
    margin:auto;
}

.profile-image{
    width:140px;
    height:140px;
    border-radius:50%;
    object-fit:cover;
    border:5px solid #fff;
    box-shadow:0 5px 20px rgba(0,0,0,.15);
}

.camera-btn{
    position:absolute;
    right:0;
    bottom:5px;
    width:45px;
    height:45px;
    border:none;
    border-radius:50%;
    background:#0d6efd;
    color:white;
    font-size:18px;
    box-shadow:0 4px 10px rgba(0,0,0,.2);
}

Hasilnya akan seperti:

       ○○○○○○○○
     ○           ○
    ○    FOTO     ○
     ○           ○
       ○○○○○○○○
             📷

Modal Upload Modern

Saat tombol kamera diklik:

<div class="modal fade" id="uploadFotoModal">

Isi modal:

┌────────────────────┐
│ Update Foto Profil │
├────────────────────┤
│  📷 Ambil Foto     │
│                    │
│  🖼️ Pilih Galeri   │
│                    │
│  🗑️ Hapus Foto     │
└────────────────────┘

Bootstrap:

<div class="list-group">

<a href="#" class="list-group-item list-group-item-action">
    <i class="bi bi-camera me-2"></i>
    Ambil Foto
</a>

<a href="#" class="list-group-item list-group-item-action">
    <i class="bi bi-image me-2"></i>
    Pilih dari Galeri
</a>

<a href="#" class="list-group-item list-group-item-action text-danger">
    <i class="bi bi-trash me-2"></i>
    Hapus Foto
</a>

</div>

Preview Sebelum Simpan

Seperti WhatsApp:

<input type="file"
       id="photoInput"
       accept="image/*"
       hidden>

<img id="preview"
     src="foto-default.jpg">

Javascript:

document
.getElementById('photoInput')
.addEventListener('change', function(e){

    const file = e.target.files[0];

    if(file){
        document.getElementById('preview').src =
            URL.createObjectURL(file);
    }

});

Level Premium (Rekomendasi)

Untuk aplikasi bimbel Gardenia 1, saya akan membuat:

  • Foto profil besar di tengah
  • Tombol kamera floating
  • Modal Bottom Sheet seperti aplikasi Android modern
  • Preview foto langsung
  • Crop foto sebelum upload
  • Kompres otomatis
  • Drag & Drop di desktop
  • Pilih Kamera/Galeri di smartphone
  • Animasi halus Bootstrap 5

Tampilannya akan sangat mirip pengalaman pengguna di Instagram dan WhatsApp, sehingga terlihat profesional dan modern.

admin

<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

<title>Admin Dashboard - Bimbel Al Qur'an</title>

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">

<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" rel="stylesheet">

<style>

body{
    background:#f8fafc;
    font-family:'Segoe UI',sans-serif;
}

.sidebar{
    width:280px;
    min-height:100vh;
    background:linear-gradient(
    180deg,
    #0f766e,
    #115e59);
    position:fixed;
    left:0;
    top:0;
    color:white;
}

.logo{
    padding:25px;
    text-align:center;
    border-bottom:1px solid rgba(255,255,255,.1);
}

.logo h4{
    margin:0;
    font-weight:700;
}

.menu a{
    display:block;
    color:white;
    text-decoration:none;
    padding:14px 25px;
    transition:.3s;
}

.menu a:hover{
    background:rgba(255,255,255,.1);
    padding-left:35px;
}

.menu i{
    width:25px;
}

.content{
    margin-left:280px;
    padding:30px;
}

.topbar{
    background:white;
    border-radius:20px;
    padding:15px 25px;
    box-shadow:0 10px 30px rgba(0,0,0,.05);
}

.stat-card{
    background:white;
    border:none;
    border-radius:24px;
    padding:25px;
    box-shadow:0 10px 25px rgba(0,0,0,.05);
    transition:.3s;
}

.stat-card:hover{
    transform:translateY(-5px);
}

.icon-box{
    width:60px;
    height:60px;
    border-radius:15px;
    display:flex;
    align-items:center;
    justify-content:center;
    font-size:24px;
    color:white;
}

.bg-green{
    background:#0f766e;
}

.bg-gold{
    background:#D4AF37;
}

.bg-blue{
    background:#2563eb;
}

.bg-red{
    background:#dc2626;
}

.card-premium{
    background:white;
    border:none;
    border-radius:24px;
    box-shadow:0 10px 30px rgba(0,0,0,.05);
}

.table thead{
    background:#f1f5f9;
}

.badge-status{
    background:#dcfce7;
    color:#166534;
    padding:8px 12px;
    border-radius:30px;
}

</style>
</head>
<body>

<!-- SIDEBAR -->

<div class="sidebar">

<div class="logo">
<h4>📖 Al Qur'an Academy</h4>
<small>Admin Panel</small>
</div>

<div class="menu mt-3">

<a href="#">
<i class="fas fa-home"></i>
Dashboard
</a>

<a href="#">
<i class="fas fa-user-graduate"></i>
Data Santri
</a>

<a href="#">
<i class="fas fa-chalkboard-teacher"></i>
Pengajar
</a>

<a href="#">
<i class="fas fa-video"></i>
Kelas Online
</a>

<a href="#">
<i class="fas fa-calendar"></i>
Jadwal
</a>

<a href="#">
<i class="fas fa-check-circle"></i>
Absensi
</a>

<a href="#">
<i class="fas fa-book-quran"></i>
Hafalan
</a>

<a href="#">
<i class="fas fa-wallet"></i>
Pembayaran
</a>

<a href="#">
<i class="fas fa-certificate"></i>
Sertifikat
</a>

<a href="#">
<i class="fas fa-chart-line"></i>
Laporan
</a>

<a href="#">
<i class="fas fa-gear"></i>
Pengaturan
</a>

</div>

</div>

<!-- CONTENT -->

<div class="content">

<!-- TOPBAR -->

<div class="topbar d-flex justify-content-between align-items-center">

<div>
<h4 class="mb-0 fw-bold">
Dashboard Admin
</h4>
<small class="text-muted">
Selamat Datang Kembali
</small>
</div>

<div class="d-flex align-items-center gap-3">

<button class="btn btn-light">
<i class="fas fa-bell"></i>
</button>

<img src="https://ui-avatars.com/api/?name=Admin"
width="45"
class="rounded-circle">

</div>

</div>

<!-- STATISTIK -->

<div class="row mt-4">

<div class="col-lg-3 mb-3">
<div class="stat-card">

<div class="d-flex justify-content-between">

<div>
<p class="text-muted mb-1">
Total Santri
</p>
<h3>1,254</h3>
</div>

<div class="icon-box bg-green">
<i class="fas fa-user-graduate"></i>
</div>

</div>

</div>
</div>

<div class="col-lg-3 mb-3">
<div class="stat-card">

<div class="d-flex justify-content-between">

<div>
<p class="text-muted mb-1">
Pengajar
</p>
<h3>36</h3>
</div>

<div class="icon-box bg-blue">
<i class="fas fa-chalkboard-teacher"></i>
</div>

</div>

</div>
</div>

<div class="col-lg-3 mb-3">
<div class="stat-card">

<div class="d-flex justify-content-between">

<div>
<p class="text-muted mb-1">
Kelas Aktif
</p>
<h3>72</h3>
</div>

<div class="icon-box bg-gold">
<i class="fas fa-video"></i>
</div>

</div>

</div>
</div>

<div class="col-lg-3 mb-3">
<div class="stat-card">

<div class="d-flex justify-content-between">

<div>
<p class="text-muted mb-1">
Pendapatan
</p>
<h3>Rp 24 Jt</h3>
</div>

<div class="icon-box bg-red">
<i class="fas fa-wallet"></i>
</div>

</div>

</div>
</div>

</div>

<!-- TABLE -->

<div class="card-premium p-4 mt-3">

<h5 class="fw-bold mb-4">
Santri Terbaru
</h5>

<div class="table-responsive">

<table class="table align-middle">

<thead>
<tr>
<th>Nama</th>
<th>Program</th>
<th>Pengajar</th>
<th>Status</th>
</tr>
</thead>

<tbody>

<tr>
<td>Ahmad Fauzi</td>
<td>Tahsin Dasar</td>
<td>Ust. Abdullah</td>
<td>
<span class="badge-status">
Aktif
</span>
</td>
</tr>

<tr>
<td>Fatimah Zahra</td>
<td>Tahfidz</td>
<td>Ustadzah Aisyah</td>
<td>
<span class="badge-status">
Aktif
</span>
</td>
</tr>

<tr>
<td>Muhammad Ali</td>
<td>Iqra'</td>
<td>Ust. Hasan</td>
<td>
<span class="badge-status">
Aktif
</span>
</td>
</tr>

</tbody>

</table>

</div>

</div>

</div>

</body>
</html>

Selasa, 02 Juni 2026

modal

Jika ikon plus tersebut ingin membuka modal Bootstrap 5 saat diklik, ubah kode ikon menjadi:

<i class="bi bi-plus-lg me-3"
   data-bs-toggle="modal"
   data-bs-target="#modalTambahSiswa"
   style="cursor:pointer"></i>

Kemudian tambahkan kode modal berikut sebelum tag </body>:

<!-- Modal Tambah Siswa -->
<div class="modal fade"
     id="modalTambahSiswa"
     tabindex="-1"
     aria-hidden="true">

    <div class="modal-dialog modal-dialog-centered">

        <div class="modal-content border-0 rounded-4">

            <div class="modal-header">
                <h5 class="modal-title fw-bold">
                    Tambah Siswa
                </h5>

                <button type="button"
                        class="btn-close"
                        data-bs-dismiss="modal">
                </button>
            </div>

            <div class="modal-body">

                <div class="mb-3">
                    <label class="form-label">
                        Nama Siswa
                    </label>

                    <input type="text"
                           class="form-control"
                           placeholder="Masukkan nama siswa">
                </div>

                <div class="mb-3">
                    <label class="form-label">
                        Nomor WhatsApp
                    </label>

                    <input type="text"
                           class="form-control"
                           placeholder="08xxxxxxxxxx">
                </div>

                <div class="mb-3">
                    <label class="form-label">
                        Program/Kelas
                    </label>

                    <select class="form-select">
                        <option>English For Kids</option>
                        <option>English For Teens</option>
                        <option>Bimbel SD</option>
                        <option>Bimbel SMP</option>
                    </select>
                </div>

            </div>

            <div class="modal-footer">

                <button type="button"
                        class="btn btn-light"
                        data-bs-dismiss="modal">
                    Batal
                </button>

                <button type="submit"
                        class="btn btn-primary">
                    Simpan
                </button>

            </div>

        </div>

    </div>

</div>

Jangan lupa memastikan file Bootstrap JS sudah dimuat:

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>

Jika aplikasi ini untuk manajemen bimbel, saya justru menyarankan modal yang lebih modern berisi menu pilihan seperti:

+ Tambah Siswa
+ Tambah Tagihan
+ Catat Pembayaran
+ Cetak Kartu SPP

sehingga satu tombol + dapat digunakan untuk berbagai aksi tanpa memenuhi tampilan halaman.

 
Design by Free WordPress Themes | Bloggerized by Lasantha - Premium Blogger Themes | Press Release Distribution