Aplikasi yang Anda jalankan ini adalah **Versi Simulasi Front-End** (JavaScript/Canvas). Untuk menerapkan aplikasi ini ke server lokal (XAMPP / Apache), gunakan struktur database MySQL dan skrip PHP Native di bawah ini untuk menangani *Backend* (AJAX Simpan Data).
1. database.sql (MySQL)
CREATE DATABASE cctv_maintenance;
USE cctv_maintenance;
CREATE TABLE maintenance_header (
id INT AUTO_INCREMENT PRIMARY KEY,
tanggal DATE NOT NULL,
lokasi_cabang VARCHAR(100) NOT NULL,
nama_teknisi VARCHAR(100) NOT NULL,
nama_pic VARCHAR(100) NOT NULL,
nvr_kapasitas INT DEFAULT 16,
nvr_model VARCHAR(100),
nvr_hdd VARCHAR(50),
nvr_retensi INT,
nvr_timesync VARCHAR(50),
nvr_temp VARCHAR(50),
nvr_power VARCHAR(50),
nvr_notes TEXT,
ttd_teknisi LONGTEXT,
ttd_pic LONGTEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE maintenance_details (
id INT AUTO_INCREMENT PRIMARY KEY,
header_id INT,
cam_index INT,
is_active BOOLEAN DEFAULT TRUE,
tipe_kamera VARCHAR(20) DEFAULT 'dome',
lantai VARCHAR(50),
area VARCHAR(100),
fisik_lensa VARCHAR(50),
fokus_angle VARCHAR(50),
koneksi VARCHAR(50),
rekaman VARCHAR(50),
tindakan TEXT,
foto_evidence JSON, -- Menyimpan Array URL/Base64 dari banyak foto
FOREIGN KEY (header_id) REFERENCES maintenance_header(id) ON DELETE CASCADE
);
2. simpan_maintenance.php (AJAX Endpoint)
<?php
// config.php -> $conn = new mysqli("localhost", "root", "", "cctv_maintenance");
include 'config.php';
header('Content-Type: application/json');
$data = json_decode(file_get_contents('php://input'), true);
if($data) {
// 1. Insert Header Info & NVR
$stmt = $conn->prepare("INSERT INTO maintenance_header (tanggal, lokasi_cabang, nama_teknisi, nama_pic, nvr_kapasitas, nvr_model, nvr_hdd, nvr_retensi, nvr_timesync, nvr_temp, nvr_power, nvr_notes, ttd_teknisi, ttd_pic) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
$stmt->bind_param("ssssisssssssss",
$data['checkDate'], $data['branchLocation'], $data['technicianName'], $data['picName'],
$data['nvr']['capacity'], $data['nvr']['model'], $data['nvr']['hdd'], $data['nvr']['retention'],
$data['nvr']['timesync'], $data['nvr']['temp'], $data['nvr']['power'], $data['nvr']['notes'],
$data['ttdTech'], $data['ttdPic']
);
$stmt->execute();
$header_id = $stmt->insert_id;
$stmt->close();
// 2. Insert Camera Details Loop
$stmt2 = $conn->prepare("INSERT INTO maintenance_details (header_id, cam_index, is_active, tipe_kamera, lantai, area, fisik_lensa, fokus_angle, koneksi, rekaman, tindakan, foto_evidence) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
foreach($data['cameras'] as $cam) {
$is_active = $cam['isActive'] ? 1 : 0;
$fotos_json = isset($cam['fotos']) ? json_encode($cam['fotos']) : '[]';
$stmt2->bind_param("iiisssssssss",
$header_id, $cam['id'], $is_active, $cam['tipe'], $cam['lantai'], $cam['area'],
$cam['fisik'], $cam['fokus'], $cam['koneksi'], $cam['rekaman'], $cam['tindakan'], $fotos_json
);
$stmt2->execute();
}
$stmt2->close();
echo json_encode(["status" => "success", "message" => "Laporan tersimpan di Database!"]);
} else {
echo json_encode(["status" => "error", "message" => "Data kosong."]);
}
?>