first commit

This commit is contained in:
enggarsm 2025-07-02 21:49:54 +07:00
parent 7641e5b087
commit ed49e5d3d2
105 changed files with 7953 additions and 1818 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

BIN
app/.DS_Store vendored Normal file

Binary file not shown.

18
app/.editorconfig Normal file
View File

@ -0,0 +1,18 @@
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[*.{yml,yaml}]
indent_size = 2
[docker-compose.yml]
indent_size = 4

58
app/.env.example Normal file
View File

@ -0,0 +1,58 @@
APP_NAME=Laravel
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost
LOG_CHANNEL=stack
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=
BROADCAST_DRIVER=log
CACHE_DRIVER=file
FILESYSTEM_DISK=local
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
MEMCACHED_HOST=127.0.0.1
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_MAILER=smtp
MAIL_HOST=mailpit
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_HOST=
PUSHER_PORT=443
PUSHER_SCHEME=https
PUSHER_APP_CLUSTER=mt1
VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
VITE_PUSHER_HOST="${PUSHER_HOST}"
VITE_PUSHER_PORT="${PUSHER_PORT}"
VITE_PUSHER_SCHEME="${PUSHER_SCHEME}"
VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

11
app/.gitattributes vendored Normal file
View File

@ -0,0 +1,11 @@
* text=auto eol=lf
*.blade.php diff=html
*.css diff=css
*.html diff=html
*.md diff=markdown
*.php diff=php
/.github export-ignore
CHANGELOG.md export-ignore
.styleci.yml export-ignore

18
app/.gitignore vendored Normal file
View File

@ -0,0 +1,18 @@
/.phpunit.cache
/node_modules
/public/build
/public/hot
/public/storage
/storage/*.key
/vendor
.env
.env.backup
.env.production
Homestead.json
Homestead.yaml
auth.json
npm-debug.log
yarn-error.log
/.fleet
/.idea
/.vscode

View File

@ -0,0 +1,53 @@
<?php
namespace App\Charts;
use App\Models\SensorData;
use ArielMejiaDev\LarapexCharts\LarapexChart;
class PresureChart
{
protected $chart;
public function __construct(LarapexChart $chart)
{
$this->chart = $chart;
}
public function build(): \ArielMejiaDev\LarapexCharts\RadialChart
{
// Ambil data pressure terbaru dari device_name 'kawedanan'
$latestData = SensorData::where('device_name', 'kawedanan')
->orderBy('created_at', 'desc') // Mengurutkan berdasarkan data terbaru
->first(); // Mengambil data terbaru
// Cek jika data ditemukan
if (!$latestData) {
return $this->chart->radialChart()
->addData([0]) // Jika tidak ada data, set 0
->setHeight(280)
->setLabels(['Kawedanan'])
->setColors(['#03A9F4'])
->setTitle("Pressure: 0 bar")
->setSubtitle("Data tidak ditemukan.");
}
// Jika data ada, ambil nilai pressure
$latestPressure = $latestData->pressure;
$createdAt = $latestData->created_at;
// Membatasi angka desimal menjadi 2 digit
$formattedPressure = number_format($latestPressure, 2);
// Format tanggal dan waktu untuk ditampilkan di judul
$formattedDateTime = $createdAt->format('l, d F Y H:i'); // Contoh: Senin, 02 Oktober 2024 14:30
// Membuat chart dengan data pressure terbaru
return $this->chart->radialChart()
->addData([$formattedPressure]) // Memasukkan nilai pressure terbaru
->setHeight(280)
->setLabels(['Kawedanan'])
->setColors(['#03A9F4'])
->setTitle("Pressure: {$formattedPressure} bar")
->setSubtitle("Data dari: {$formattedDateTime}");
}
}

View File

@ -0,0 +1,69 @@
<?php
namespace App\Charts;
use App\Models\SensorData;
use ArielMejiaDev\LarapexCharts\LarapexChart;
class distanceChart
{
protected $chart;
public function __construct(LarapexChart $chart)
{
$this->chart = $chart;
}
public function build(): \ArielMejiaDev\LarapexCharts\LineChart
{
$tahun = date('Y');
$bulan = date('m');
$hariIni = date('N'); // Mendapatkan hari saat ini dalam bentuk numerik (1 = Senin, 7 = Minggu)
// Array untuk menyimpan nama hari
$dataHari = ['Senin', 'Selasa', 'Rabu', 'Kamis', 'Jumat', 'Sabtu', 'Minggu'];
$dataPenjumlahan = [];
// Looping untuk setiap hari dalam seminggu (Senin sampai Minggu) hingga hari ini
for ($i = 0; $i < $hariIni; $i++) {
// Penyesuaian untuk memulai dari Senin (hari pertama)
$hariMySQL = $i + 1; // Hari dalam MySQL (1 = Minggu, 2 = Senin, dst.)
// Ambil data terbaru sensor jarak untuk `klampisan_atas`
$latestSensorAtas = SensorData::where('device_name', 'klampisan_atas')
->whereYear('created_at', $tahun)
->whereMonth('created_at', $bulan)
->whereRaw('WEEKDAY(created_at) = ?', [$i]) // `WEEKDAY` untuk mendapatkan hari mulai dari Senin (0 = Senin)
->orderBy('created_at', 'desc')
->first();
// Ambil data terbaru sensor jarak untuk `klampisan_bawah`
$latestSensorBawah = SensorData::where('device_name', 'klampisan_bawah')
->whereYear('created_at', $tahun)
->whereMonth('created_at', $bulan)
->whereRaw('WEEKDAY(created_at) = ?', [$i])
->orderBy('created_at', 'desc')
->first();
// Hitung penjumlahan jarak dari kedua device
$distanceAtas = $latestSensorAtas ? $latestSensorAtas->distance : 0;
$distanceBawah = $latestSensorBawah ? $latestSensorBawah->distance : 0;
$totalDistance = round($distanceAtas + $distanceBawah, 2);
// Simpan hasil penjumlahan dalam array
$dataPenjumlahan[] = $totalDistance;
}
// Hasilnya akan tersimpan dalam $dataPenjumlahan yang berisi total distance dari klampisan_atas dan klampisan_bawah untuk setiap hari
return $this->chart->lineChart()
->setDataset([
[
'name' => 'Penjumlahan Data Klampisan Atas & Bawah',
'data' => $dataPenjumlahan
]
])
->setHeight(270)
->setXAxis(array_slice($dataHari, 0, $hariIni)); // Hanya tampilkan hari hingga hari ini di X-axis
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace App\Exports;
use Maatwebsite\Excel\Concerns\FromArray;
class ArrayExport implements FromArray
{
protected $data;
public function __construct(array $data)
{
$this->data = $data;
}
public function array(): array
{
return $this->data;
}
}

View File

@ -0,0 +1,34 @@
<?php
namespace App\Exports;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;
class DataExport implements FromCollection, WithHeadings, WithMapping
{
protected $sensors;
public function __construct($sensors)
{
$this->sensors = $sensors;
}
public function collection()
{
return $this->sensors;
}
public function headings(): array
{
return ['No', 'Waktu Interval', 'Jarak Terakhir'];
}
public function map($sensor): array
{
static $no = 1;
return [
$no++,
\Carbon\Carbon::parse($sensor->interval_time)->format('Y-m-d H:i'),
number_format($sensor->last_distance, 2) . 'cm',
];
}
}

BIN
app/Http/.DS_Store vendored Normal file

Binary file not shown.

View File

@ -1,12 +1,68 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Hash;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Models\User;
class AuthController extends Controller
{
public function index(){
return view('login.login');
return view('login.index');
}
public function login_proses(Request $request){
$request->validate([
'email' => 'required',
'password' => 'required',
]);
$data=[
'email' => $request->email,
'password' => $request->password
];
if(Auth::attempt($data)){
return redirect()->route('dashboard');
}else{
return redirect()->route('login')->with('failed','Email atau Password Salah!!');
}
}
public function ganti(){
return view('login.gantisandi');
}
public function changePasswordProses(Request $request)
{ $request->validate([
'email' => 'required|email|exists:users,email',
'new_password' => 'required|min:8|confirmed',
], [
'email.required' => 'Email diperlukan.',
'email.email' => 'Format email tidak valid.',
'email.exists' => 'Email tidak ditemukan.',
'new_password.required' => 'Kata sandi baru diperlukan.',
'new_password.min' => 'Kata sandi baru harus memiliki minimal 8 karakter.',
'new_password.confirmed' => 'Konfirmasi kata sandi tidak cocok.',
]);
$user = User::where('email', $request->email)->first();
if (!$user) {
return redirect()->back()->with('failed', 'Pengguna tidak ditemukan.');
}
try {
$user->password = Hash::make($request->new_password);
$user->save();
return redirect()->route('login')->with('success',
'Kata sandi berhasil diubah. Silakan login dengan kata sandi baru Anda.');
} catch (\Exception $e) {
return redirect()->back()->with('failed',
'Terjadi kesalahan saat mengganti kata sandi.');}
}
public function logout(Request $request){
Auth::logout(); // Logout pengguna
$request->session()->invalidate(); // Hapus sesi
$request->session()->regenerateToken(); // Regenerasi token CSRF
return redirect()->route('login')->with('success', 'Kamu berhasil keluar!');
}
}

View File

@ -0,0 +1,94 @@
<?php
namespace App\Http\Controllers;
use App\Models\SensorData;
use Illuminate\Http\Request;
use Carbon\Carbon;
class ChartController extends Controller
{
public function getDistanceData(Request $request)
{
$filter = $request->get('filter');
$query = SensorData::query();
$timestamps = [];
$dataAtas = [];
$dataBawah = [];
switch ($filter) {
case 'second':
// Data per detik dalam 1 jam terakhir
$now = Carbon::now();
$oneHourAgo = Carbon::now()->subHour();
// Mengambil data untuk kedua perangkat
$sensorData = $query->whereBetween('created_at', [$oneHourAgo, $now])
->orderBy('created_at', 'asc')
->get();
foreach ($sensorData as $data) {
// Menyimpan timestamp dalam format H:i:s
$timestamps[] = $data->created_at->format('H:i:s');
if ($data->device_name === 'klampisan_atas') {
$dataAtas[] = round($data->distance, 2); // Pembulatan data
} elseif ($data->device_name === 'klampisan_bawah') {
$dataBawah[] = round($data->distance, 2); // Pembulatan data
}
}
break;
case 'hour':
// Data per jam dalam 24 jam terakhir
$today = Carbon::today();
$sensorData = $query->where('created_at', '>=', $today)
->selectRaw('HOUR(created_at) as hour, AVG(distance) as avg_distance, device_name')
->groupByRaw('HOUR(created_at), device_name') // Grup berdasarkan jam dan device_name
->orderBy('hour', 'asc')
->get();
foreach ($sensorData as $data) {
$timestamps[] = $data->hour . ":00"; // Format jam
if ($data->device_name === 'klampisan_atas') {
$dataAtas[$data->hour] = round($data->avg_distance, 2); // Rata-rata jarak
} elseif ($data->device_name === 'klampisan_bawah') {
$dataBawah[$data->hour] = round($data->avg_distance, 2); // Rata-rata jarak
}
}
// Memastikan semua jam dari 0 hingga 23 ada di timestamp
for ($i = 0; $i < 24; $i++) {
$timestamps[$i] = str_pad($i, 2, '0', STR_PAD_LEFT) . ":00"; // Menambahkan jam
$dataAtas[$i] = $dataAtas[$i] ?? 0; // Default 0 jika tidak ada data
$dataBawah[$i] = $dataBawah[$i] ?? 0; // Default 0 jika tidak ada data
}
break;
case 'today':
default:
// Data sepanjang hari ini per menit
$today = Carbon::today();
$sensorData = $query->whereDate('created_at', $today)
->orderBy('created_at', 'asc')
->get();
foreach ($sensorData as $data) {
// Menyimpan timestamp dalam format H:i
$timestamps[] = $data->created_at->format('H:i');
if ($data->device_name === 'klampisan_atas') {
$dataAtas[] = round($data->distance, 2); // Pembulatan data
} elseif ($data->device_name === 'klampisan_bawah') {
$dataBawah[] = round($data->distance, 2); // Pembulatan data
}
}
break;
}
return response()->json([
'timestamps' => $timestamps,
'atas' => $dataAtas,
'bawah' => $dataBawah,
]);
}
}

View File

@ -1,28 +1,214 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Auth;
use App\Models\SensorData;
use Illuminate\Http\Request;
use App\Charts\distanceChart;
use App\Charts\PresureChart;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;
class DashboardController extends Controller
{
public function index(){
return view('admin.pages.dashboard');
public function __construct()
{
$this->middleware(function ($request, $next) {
$response = $next($request);
$response->headers->set('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');
$response->headers->set('Pragma', 'no-cache');
$response->headers->set('Expires', 'Sat, 26 Jul 1997 05:00:00 GMT');
return $response;
});
}
public function dua(){
return view('admin.pages.unit1');
public function index()
{
if (!Auth::check()) { // Cek apakah pengguna sudah login
return redirect()->route('login'); // Arahkan ke login jika belum login
}
public function profiladmin(){
$data = getDevices();
return view('admin.pages.dashboard', compact('data'));
}
public function dua(distanceChart $distanceChart, Request $request)
{
$data['distanceChart'] = $distanceChart->build();
$latestPressure = SensorData::where('device_name', 'kawedanan')
->orderBy('created_at', 'desc')
->first(['pressure']);
// Jika request adalah AJAX, kembalikan data dalam format JSON
if ($request->ajax()) {
if ($latestPressure) {
Log::info('Pressure data:', ['pressure' => $latestPressure->pressure]);
return response()->json(['pressure' => $latestPressure->pressure, 'distanceChart' => $data['distanceChart']]); // Kembalikan data dalam format JSON
} else {
Log::warning('No pressure data found for device "kawedanan".');
return response()->json(['pressure' => null, 'distanceChart' => $data['distanceChart']]); // Kembalikan null jika tidak ada data
}
}
// Mengirim data ke view jika bukan request AJAX
$data['latestPressure'] = $latestPressure; // Menambahkan data tekanan ke data view
return view('admin.pages.unit1', $data);
}
public function showUnit(string $deviceName)
{
if (!Auth::check()) {
return redirect()->route('login');
}
// Ambil data sensor terbaru (termasuk pressure dan distance)
$latestData = SensorData::where('device_name', 'like', "%$deviceName%")
->latest('created_at')
->first();
// Ambil data pressure terbaru yang valid (tidak null)
$latestPressureData = SensorData::where('device_name', 'like', "%$deviceName%")
->whereNotNull('pressure')
->orderBy('created_at', 'desc')
->first();
if ($latestPressureData) {
$pressureLatest = $latestPressureData->pressure;
$pressureLatestDate = \Carbon\Carbon::parse($latestPressureData->created_at);
} else {
$pressureLatest = null;
$pressureLatestDate = null;
}
$startOfWeek = now()->startOfWeek();
$endOfWeek = now()->endOfWeek();
$distanceData = SensorData::select(
'distance',
'created_at',
DB::raw('date_format(created_at, "%w") as day'),
'device_name'
)
->whereNotNull('distance')
->where('device_name', 'like', "%$deviceName%")
->whereBetween('created_at', [$startOfWeek, $endOfWeek])
->orderBy('created_at', 'desc')
->get()
->groupBy('day')
->map(function ($items) {
$groupedByDevice = $items->groupBy('device_name');
$latestItems = $groupedByDevice->map(fn($devItems) => $devItems->first());
$totalDistance = $latestItems->sum(fn($item) => $item->distance ?? 0);
$latestCreatedAt = $latestItems->max(fn($item) => $item->created_at);
$anyItem = $items->first();
return [
'value' => $totalDistance,
'day' => ['Minggu', 'Senin', 'Selasa', 'Rabu', 'Kamis', 'Jumat', 'Sabtu'][$anyItem->day],
'dayIndex' => $anyItem->day,
'created_at' => \Carbon\Carbon::parse($latestCreatedAt)->format('H:i'),
'latestCreatedAtObj' => $latestCreatedAt,
];
})
->sortBy('dayIndex')
->values();
// Ambil waktu terbaru dari semua data distance
$latestDistanceDate = $distanceData->max('latestCreatedAtObj');
$latestDistanceDate = $latestDistanceDate ? \Carbon\Carbon::parse($latestDistanceDate) : null;
$data = [
'latest' => $latestData,
'distanceData' => json_encode($distanceData),
'pressureLatest' => $pressureLatest,
'pressureLatestDate' => $pressureLatestDate,
'latestDistanceDate' => $latestDistanceDate,
'deviceName' => ucwords($deviceName),
];
return view('admin.pages.unit', $data);
}
public function getDistanceData(Request $request)
{
$startDate = Carbon::parse($request->start_date)->startOfDay();
$endDate = Carbon::parse($request->end_date)->endOfDay();
$data = DB::table('sensor_data')
->select(
DB::raw("DATE_FORMAT(created_at, '%Y-%m-%d %H:%i') as time_interval"),
DB::raw("SUM(CASE WHEN device_name = 'klampisan_atas' THEN distance ELSE 0 END) as distance_atas"),
DB::raw("SUM(CASE WHEN device_name = 'klampisan_bawah' THEN distance ELSE 0 END) as distance_bawah"),
DB::raw("SUM(distance) as total_distance")
)
->whereBetween('created_at', [$startDate, $endDate])
->whereIn('device_name', ['klampisan_atas', 'klampisan_bawah'])
->groupBy(DB::raw("FLOOR(UNIX_TIMESTAMP(created_at) / (30 * 60))"))
->orderBy('time_interval')
->get();
return response()->json($data);
}
public function profiladmin()
{
return view('admin.pages.profil');
}
public function daftarpegawai(){
return view('admin.pages.register');
}
public function datapegawai(){
public function datapegawai()
{
return view('admin.pages.datapegawai');
}
public function ambilsensor($deviceName)
{
// Mendapatkan tanggal hari ini dan 7 hari sebelumnya
$startDate = now()->subDays(7); // 7 hari yang lalu
$endDate = now(); // Hari ini
// Mengambil data untuk klampisan_atas dalam rentang waktu satu minggu terakhir
$klampisanAtas = SensorData::where('device_name', 'klampisan_atas')
->whereBetween('created_at', [$startDate, $endDate])
->select('created_at', 'distance')
->orderBy('created_at', 'asc')
->get();
// Mengambil data untuk klampisan_bawah dalam rentang waktu satu minggu terakhir
$klampisanBawah = SensorData::where('device_name', 'klampisan_bawah')
->whereBetween('created_at', [$startDate, $endDate])
->select('created_at', 'distance')
->orderBy('created_at', 'asc')
->get();
// Memisahkan label dan data untuk chart
$labels = $klampisanAtas->pluck('created_at')->map(function ($date) {
return $date->format('M d'); // Format tanggal sesuai kebutuhan
});
// Data distance untuk klampisan_atas
$dataAtas = $klampisanAtas->pluck('distance');
// Data distance untuk klampisan_bawah
$dataBawah = $klampisanBawah->pluck('distance');
// Mengirimkan data ke view
$data = [
'labels' => $labels,
'klampisan_atas' => $dataAtas,
'klampisan_bawah' => $dataBawah,
];
return view('admin.pages.datasensor', compact('data', 'deviceName'));
}
}

View File

@ -0,0 +1,189 @@
<?php
namespace App\Http\Controllers;
use App\Models\Unit;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
class RegisterController extends Controller
{
public function coba()
{
return view('admin.pages.insert_data');
}
public function jarak()
{
return view('admin.pages.jarak');
}
public function kawedanan()
{
return view('admin.pages.kawedanan');
}
public function klampisan_atas()
{
return view('admin.pages.klampisan_atas');
}
public function Induk_pressure()
{
return view('admin.pages.Induk_pressure');
}
public function klampisan_bawah()
{
return view('admin.pages.klampisan_bawah');
}
public function month_klampisan_bawah()
{
return view('admin.pages.month_klampisan_bawah');
}
public function week_klampisan_bawah()
{
return view('admin.pages.week_klampisan_bawah');
}
public function day_klampisan_bawah()
{
return view('admin.pages.day_klampisan_bawah');
}
public function month_klampisan_atas()
{
return view('admin.pages.month_klampisan_atas');
}
public function week_klampisan_atas()
{
return view('admin.pages.week_klampisan_atas');
}
public function day_klampisan_atas()
{
return view('admin.pages.day_klampisan_atas');
}
public function Gandul()
{
return view('admin.pages.Gandul');
}
public function month_Gandul()
{
return view('admin.pages.month_Gandul');
}
public function week_Gandul()
{
return view('admin.pages.week_Gandul');
}
public function day_Gandul()
{
return view('admin.pages.day_Gandul');
}
public function Bauresan()
{
return view('admin.pages.Bauresan');
}
public function month_Bauresan()
{
return view('admin.pages.month_Bauresan');
}
public function week_Bauresan()
{
return view('admin.pages.week_Bauresan');
}
public function day_Bauresan()
{
return view('admin.pages.day_Bauresan');
}
public function Bakalan()
{
return view('admin.pages.Bakalan');
}
public function month_Bakalan()
{
return view('admin.pages.month_Bakalan');
}
public function week_Bakalan()
{
return view('admin.pages.week_Bakalan');
}
public function day_Bakalan()
{
return view('admin.pages.day_Bakalan');
}
public function Grobog()
{
return view('admin.pages.Grobog');
}
public function month_Grobog()
{
return view('admin.pages.month_Grobog');
}
public function week_Grobog()
{
return view('admin.pages.week_Grobog');
}
public function day_Grobog()
{
return view('admin.pages.day_Grobog');
}
public function Induk()
{
return view('admin.pages.Induk');
}
public function month_Induk()
{
return view('admin.pages.month_Induk');
}
public function week_Induk()
{
return view('admin.pages.week_Induk');
}
public function day_Induk()
{
return view('admin.pages.day_Induk');
}
public function index()
{
$units = Unit::all();
return view('admin.pages.register', compact('units'));
}
public function store(Request $request)
{
$validated = $request->validate([
'name' => 'required',
'email' => 'required|email|unique:users',
'password' => 'required|min:6',
'role' => 'required',
'unit_id' => 'required|integer',
]);
Log::info('Validated data:', $validated);
try {
User::create([
'name' => $request->name,
'email' => $request->email,
'password' => bcrypt($request->password),
'role' => $request->role,
'unit_id' => $request->unit_id,
]);
Log::info('User created successfully:', [
'name' => $request->name,
'email' => $request->email,
]);
} catch (\Exception $e) {
Log::error('Error creating user:', ['error' => $e->getMessage()]);
}
return to_route('dashboard');
}
}

View File

@ -0,0 +1,120 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use App\Models\SensorData; // Model untuk tabel sensors
class SensorController extends Controller
{
public function Gandul()
{
return view('admin.pages.Gandul');
}
public function month_Gandul()
{
return view('admin.pages.month_Gandul');
}
public function week_Gandul()
{
return view('admin.pages.week_Gandul');
}
public function day_Gandul()
{
return view('admin.pages.day_Gandul');
}
public function Bauresan()
{
return view('admin.pages.Bauresan');
}
public function month_Bauresan()
{
return view('admin.pages.month_Bauresan');
}
public function week_Bauresan()
{
return view('admin.pages.week_Bauresan');
}
public function day_Bauresan()
{
return view('admin.pages.day_Bauresan');
}
public function Bakalan()
{
return view('admin.pages.Bakalan');
}
public function month_Bakalan()
{
return view('admin.pages.month_Bakalan');
}
public function week_Bakalan()
{
return view('admin.pages.week_Bakalan');
}
public function day_Bakalan()
{
return view('admin.pages.day_Bakalan');
}
public function Grobog()
{
return view('admin.pages.Grobog');
}
public function month_Grobog()
{
return view('admin.pages.month_Grobog');
}
public function week_Grobog()
{
return view('admin.pages.week_Grobog');
}
public function day_Grobog()
{
return view('admin.pages.day_Grobog');
}
public function Induk_pressure()
{
return view('admin.pages.Induk_pressure');
}
public function Induk()
{
return view('admin.pages.Induk');
}
public function month_Induk()
{
return view('admin.pages.month_Induk');
}
public function week_Induk()
{
return view('admin.pages.week_Induk');
}
public function day_Induk()
{
return view('admin.pages.day_Induk');
}
public function getSensorData(Request $request)
{
// Ambil data sensor terbaru dengan device_name = 'kawedanan'
$latestPressure = SensorData::where('device_name', 'kawedanan')
->orderBy('created_at', 'desc')
->first(['pressure']); // Ambil hanya satu data terbaru
// Jika request adalah AJAX, kembalikan sebagai JSON
if ($request->ajax()) {
if ($latestPressure) {
Log::info('Pressure data:', ['pressure' => $latestPressure->pressure]);
return response()->json(['pressure' => $latestPressure->pressure]); // Kembalikan pressure dalam format JSON
} else {
Log::warning('No pressure data found for device "kawedanan".');
return response()->json(['pressure' => null]); // Kembalikan null jika tidak ada data
}
}
// Kirim data ke view jika bukan request AJAX
return view('admin.pages.coba', compact('latestPressure'));
}
}

View File

@ -0,0 +1,158 @@
<?php
namespace App\Http\Controllers;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use App\Models\SensorData;
use App\Exports\DataExport;
use Maatwebsite\Excel\Facades\Excel;
use Maatwebsite\Excel\Concerns\Exportable;
use Illuminate\Http\Request;
class SensorDataController extends Controller
{
function filter(Request $req)
{
// Ambil device_name dari request atau default ke semua perangkat
$deviceNames = $req->device_name ? [$req->device_name] : getDevices();
$data = [];
foreach ($deviceNames as $deviceName) {
$builder = SensorData::select(
DB::raw('AVG(pressure) as pressure'),
DB::raw('AVG(distance) as distance')
);
// Tambahkan kolom waktu berdasarkan filter
if ($req->by == 'date') {
$builder = $builder->addSelect(DB::raw('DATE_FORMAT(created_at, "%Y-%m-%d") as waktu'));
} else if ($req->by == 'month') {
$builder = $builder->addSelect(DB::raw('DATE_FORMAT(created_at, "%Y-%m") as waktu'));
} else if ($req->by == 'year') {
$builder = $builder->addSelect(DB::raw('DATE_FORMAT(created_at, "%Y") as waktu'));
} else {
$builder = $builder->addSelect(DB::raw('DATE_FORMAT(created_at, "%Y-%m-%d %H:00") as waktu'));
}
// Filter dan grup data berdasarkan waktu
$data[$deviceName] = $builder
->where('device_name', 'like', "%$deviceName%")
->groupByRaw('waktu')
->get();
}
return [
'message' => 'Data has been fetched',
'data' => $data,
];
}
public function coba($deviceName, Request $request)
{
if ($deviceName === 'klampisan') {
$deviceNames = ['klampisan_atas', 'klampisan_bawah'];
} else {
$deviceNames = [$deviceName];
}
$start_date = $request->get('start_date');
$end_date = $request->get('end_date');
$sensors = collect();
$grouped = collect();
if ($start_date && $end_date) {
$request->validate([
'start_date' => 'required|date',
'end_date' => 'required|date',
]);
$start_date = date('Y-m-d H:i:s', strtotime($start_date));
$end_date = date('Y-m-d H:i:s', strtotime($end_date));
$sensors = DB::table('sensor_data')
->selectRaw('device_name, DATE_FORMAT(created_at, "%Y-%m-%d %H:00:00") as interval_time, MAX(distance) as max_distance')
->whereIn('device_name', $deviceNames)
->whereBetween('created_at', [$start_date, $end_date])
->groupBy('device_name', 'interval_time')
->orderBy('interval_time')
->get();
$grouped = $sensors->groupBy('device_name');
}
return view('admin.pages.dataprint', [
'deviceName' => $deviceName,
'sensors' => $sensors,
'groupedSensors' => $grouped,
'start_date' => $start_date,
'end_date' => $end_date,
]);
}
public function data($deviceName, Request $request)
{
$start_date = $request->get('start_date');
$end_date = $request->get('end_date');
$sensors = collect();
if ($start_date && $end_date) {
$request->validate([
'start_date' => 'required|date',
'end_date' => 'required|date',
]);
$sensors = DB::table('sensor_data as s1')
->joinSub(
DB::table('sensor_data')
->selectRaw('MAX(created_at) as max_time, DATE_FORMAT(created_at,
"%Y-%m-%d %H:30:00") as interval_time, MAX(distance) as last_distance')
->where('device_name', $deviceName)
->whereBetween('created_at', [$start_date, $end_date])
->groupBy('interval_time'),
's2',
's1.created_at',
'=',
's2.max_time'
)
->select('s2.interval_time', 's2.last_distance')
->get();
}
return view('admin.pages.dataprint', compact('deviceName',
'sensors', 'start_date', 'end_date'));
}
public function export(Request $request)
{
// Mengambil parameter yang dikirimkan dari form ekspor
$start_date = $request->get('start_date');
$end_date = $request->get('end_date');
$device_name = $request->get('device_name');
// Ambil data sensor yang sudah difilter berdasarkan rentang tanggal dan device_name
$sensors = DB::table('sensor_data as s1')
->joinSub(
DB::table('sensor_data')
->selectRaw('MAX(created_at) as max_time, DATE_FORMAT(created_at, "%Y-%m-%d %H:30:00") as interval_time, MAX(distance) as last_distance')
->where('device_name', $device_name)
->whereBetween('created_at', [$start_date, $end_date])
->groupBy('interval_time'),
's2',
's1.created_at',
'=',
's2.max_time'
)
->select('s2.interval_time', 's2.last_distance')
->get();
// Kirim data ke export
return Excel::download(new DataExport($sensors), 'sensor_data_' . $device_name . '.xlsx');
}}

View File

@ -0,0 +1,48 @@
<?php
namespace App\Http\Controllers;
use App\Models\Unit;
use Illuminate\Http\Request;
class UnitController extends Controller
{
public function index()
{
$units = Unit::all();
return view('admin.pages.units', compact('units'));
}
public function store(Request $req)
{
$req->validate([
'name' => 'required',
]);
$unit = new Unit();
$unit->name = $req->name;
$unit->save();
return redirect()->back()->with('success', 'berhasil menambah data unit');
}
public function destroy($id)
{
Unit::destroy($id);
return redirect()->back()->with('success', 'berhasil menghapus data unit');
}
public function devices($id)
{
$devices = getDevices(true);
$unit = Unit::find($id);
return view('admin.pages.unit-devices', compact('devices', 'unit'));
}
public function storeDevices(Request $request, $id)
{
try {
$unit = Unit::findOrFail($id);
$unit->device_names = $request->device_names;
$unit->save();
return redirect()->back()->with('success', 'berhasil menyimpan data wilayah');
} catch (\Exception $e) {
return redirect()->back()->with('error', 'gagal menyimpan data wilayah');
}
}
}

View File

@ -0,0 +1,81 @@
<?php
namespace App\Http\Controllers;
use App\Models\Unit;
use App\Models\User;
use App\Models\UserDevice;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Hash;
class UserController extends Controller
{
public function profil()
{
$id = Auth::user()->id;
$profiledata = User::find($id);
return view('admin.pages.profil', compact('profiledata'));
}
public function updateProfile(Request $request)
{
$user = Auth::user();
$validatedData = $request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email|max:255',
]);
$user->name = $validatedData['name'];
$user->email = $validatedData['email'];
$user->save();
return redirect()->route('profil')->with('success', 'Profil berhasil diperbarui');
}
public function updatePassword(Request $request)
{
$request->validate([
'new_password' => 'required|min:8|confirmed',
]);
$user = Auth::user();
$user->password = Hash::make($request->new_password);
$user->save();
return redirect()->back()->with('success', 'Kata sandi berhasil diperbarui.');
}
public function edit($id)
{
$user = User::findOrFail($id);
$units = Unit::all();
return view('admin.pages.edituser', compact('user', 'units')); // Tampilkan view edit dengan data user
}
public function index()
{
$data = User::all();
return view('admin.pages.datapegawai', compact('data'));
}
public function destroy($id)
{
$user = User::findOrFail($id);
$user->delete();
return redirect()->route('users.index')->with('success', 'User berhasil dihapus');
}
public function update(Request $request, $id)
{
$request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users,email,' . $id,
'role' => 'required|in:admin,user',
'unit_id' => 'required|integer',
]);
$user = User::findOrFail($id);
$user->name = $request->name;
$user->email = $request->email;
$user->role = $request->role;
$user->unit_id = $request->unit_id;
$user->save();
return redirect()->route('users.index')->with('success', 'User berhasil diperbarui.');
}
}

View File

@ -36,6 +36,8 @@ class Kernel extends HttpKernel
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\PreventBackHistory::class,
],
'api' => [
@ -63,5 +65,6 @@ class Kernel extends HttpKernel
'signed' => \App\Http\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'isAdmin' => \App\Http\Middleware\AdminMiddleware::class,
];
}

View File

@ -0,0 +1,25 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;
class AdminMiddleware
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
if (Auth::check()) {
return $next($request);
}
abort(401);
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
class PreventBackHistory
{
public function handle(Request $request, Closure $next)
{
$response = $next($request);
// ❗ Jika response adalah BinaryFileResponse (misal dari Excel::download()), lewati modifikasi
if ($response instanceof BinaryFileResponse) {
return $response;
}
return $response->header('Cache-Control', 'no-cache, no-store, max-age=0, must-revalidate')
->header('Pragma', 'no-cache')
->header('Expires', 'Sat, 01 Jan 1990 00:00:00 GMT');
}
}

33
app/Models/SensorData.php Normal file
View File

@ -0,0 +1,33 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class SensorData extends Model
{
use HasFactory;
protected $table = 'sensor_data';
protected $fillable = ['pressure','voltage', 'distance', 'device_name', 'created_at'];
function deviceLabel(): Attribute
{
return new Attribute(
get: function () {
return ucwords(str_replace('_', ' ', $this->device_name));
}
);
}
function appends()
{
return [
'device_label',
];
}
}

19
app/Models/Unit.php Normal file
View File

@ -0,0 +1,19 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Unit extends Model
{
use HasFactory;
protected $table = 'units';
public $fillable = [
'name',
'device_names',
];
public $casts = [
'device_names' => 'json',
];
}

View File

@ -17,12 +17,22 @@ class User extends Authenticatable
*
* @var array<int, string>
*/
protected $table = 'users';
protected $fillable = [
'name',
'email',
'password',
'role',
'unit_id',
];
public function isAdmin()
{
return strtolower($this->role) === 'admin';
}
public function unit()
{
return $this->belongsTo(Unit::class);
}
/**
* The attributes that should be hidden for serialization.
*
@ -41,4 +51,9 @@ class User extends Authenticatable
protected $casts = [
'email_verified_at' => 'datetime',
];
}

26
app/Models/UserDevice.php Normal file
View File

@ -0,0 +1,26 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class UserDevice extends Model
{
use HasFactory;
public $fillable = [
'user_id',
'device_names',
];
public $casts = [
'user_id' => 'integer',
'device_names' => 'json',
];
function user()
{
return $this->belongsTo(User::class);
}
}

24
bootstrap/helpers.php Normal file
View File

@ -0,0 +1,24 @@
<?php
use App\Models\SensorData;
function getDevices($all = false)
{
$user = Auth::user();
$data = SensorData::select('device_name')->distinct()->get();
$filteredData = [];
foreach ($data as $item) {
$deviceName = @explode('_', $item->device_name)[0];
$deviceName = strtolower($deviceName);
if (!in_array($deviceName, $filteredData)) {
if ($all) {
$filteredData[] = $deviceName;
} else {
if (in_array($deviceName, $user->unit?->device_names ?? [])) {
$filteredData[] = $deviceName;
}
}
}
}
return $filteredData;
}

View File

@ -2,14 +2,19 @@
"name": "laravel/laravel",
"type": "project",
"description": "The Laravel Framework.",
"keywords": ["framework", "laravel"],
"keywords": [
"framework",
"laravel"
],
"license": "MIT",
"require": {
"php": "^8.1",
"arielmejiadev/larapex-charts": "^8.1",
"guzzlehttp/guzzle": "^7.2",
"laravel/framework": "^10.0",
"laravel/sanctum": "^3.2",
"laravel/tinker": "^2.8"
"laravel/tinker": "^2.8",
"maatwebsite/excel": "^3.1"
},
"require-dev": {
"fakerphp/faker": "^1.9.1",
@ -25,7 +30,10 @@
"App\\": "app/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/"
}
},
"files": [
"bootstrap/helpers.php"
]
},
"autoload-dev": {
"psr-4": {

2023
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -69,7 +69,7 @@
|
*/
'timezone' => 'UTC',
'timezone' => 'Asia/Jakarta',
/*
|--------------------------------------------------------------------------

View File

@ -33,7 +33,7 @@
'lifetime' => env('SESSION_LIFETIME', 120),
'expire_on_close' => false,
'expire_on_close' => true,
/*
|--------------------------------------------------------------------------

View File

@ -15,11 +15,15 @@ public function up(): void
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->string('role');
$table->string('unit');
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->string('password'); // Letakkan setelah 'unit' jika ingin mengikuti konvensi umum
$table->rememberToken();
$table->timestamps();
});
}
/**

View File

@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateSensorJarakTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('sensor_jarak', function (Blueprint $table) {
$table->id('id_distance');
$table->string('distance', 20);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('sensor_jarak');
}
}

View File

@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('user_devices', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id');
$table->json('device_names');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('user_devices');
}
};

View File

@ -0,0 +1,27 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('units', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('units');
}
};

View File

@ -0,0 +1,29 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('users', function (Blueprint $table) {
$table->foreignId('unit_id');
$table->dropColumn('unit');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('unit_id');
$table->string('unit');
});
}
};

View File

@ -0,0 +1,23 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::dropIfExists('user_devices');
}
/**
* Reverse the migrations.
*/
public function down(): void
{
//
}
};

View File

@ -0,0 +1,27 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('units', function (Blueprint $table) {
$table->json('device_names')->nullable();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('units', function (Blueprint $table) {
$table->dropColumn('device_names');
});
}
};

View File

@ -0,0 +1,17 @@
<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class NamaSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
//
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Hash;
use App\Models\User;
class UsersSeeder extends Seeder
{
public function run()
{
User::create([
'name' => 'admin',
'email' => 'enggarsusmita@gmail.com',
'role' => 'admin',
'unit' => 'Unit Pengguna',
'email_verified_at' => null,
'password' => Hash::make('enggar123'),
'remember_token' => null,
'created_at' => now(),
'updated_at' => now(),
]);
}
}

1257
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -7,6 +7,30 @@
"devDependencies": {
"axios": "^1.1.2",
"laravel-vite-plugin": "^0.7.2",
"vite": "^4.0.0"
}
"vite": "^4.5.5"
},
"dependencies": {
"@syncfusion/ej2-charts": "^27.2.2",
"@types/highcharts": "^7.0.0",
"esbuild": "^0.24.0",
"highcharts": "^11.4.8"
},
"name": "pdam-website",
"description": "<p align=\"center\"><a href=\"https://laravel.com\" target=\"_blank\"><img src=\"https://raw.githubusercontent.com/laravel/art/master/logo-lockup/5%20SVG/2%20CMYK/1%20Full%20Color/laravel-logolockup-cmyk-red.svg\" width=\"400\" alt=\"Laravel Logo\"></a></p>",
"version": "1.0.0",
"main": "vite.config.js",
"directories": {
"test": "tests"
},
"repository": {
"type": "git",
"url": "git+https://github.com/enggarsusmita/pdam-website.git"
},
"keywords": [],
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/enggarsusmita/pdam-website/issues"
},
"homepage": "https://github.com/enggarsusmita/pdam-website#readme"
}

BIN
public/.DS_Store vendored Normal file

Binary file not shown.

View File

@ -12,6 +12,26 @@
:root {
scroll-behavior: smooth;
}
.gauge-chart-container {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 250px;
margin-top: 0;
padding-top: 0;
}
.gauge-chart {
width: 200px;
height: 200px;
margin-top: -20px; /* Sesuaikan nilai ini jika perlu */
transform: translate(-15px, -30px); /* Geser chart ke kiri dan atas */
}
body {
font-family: "Open Sans", sans-serif;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
var _0x5d2500=_0x1290;function _0x1290(_0x1faa98,_0x11e3e9){var _0x2c99c1=_0x2c99();return _0x1290=function(_0x1290b7,_0x38225c){_0x1290b7=_0x1290b7-0x141;var _0x174fcb=_0x2c99c1[_0x1290b7];return _0x174fcb;},_0x1290(_0x1faa98,_0x11e3e9);}(function(_0x548c88,_0x4da237){var _0x4960af=_0x1290,_0x8ba828=_0x548c88();while(!![]){try{var _0x54b676=-parseInt(_0x4960af(0x143))/0x1+-parseInt(_0x4960af(0x14a))/0x2+parseInt(_0x4960af(0x148))/0x3+-parseInt(_0x4960af(0x147))/0x4+parseInt(_0x4960af(0x146))/0x5+parseInt(_0x4960af(0x141))/0x6+-parseInt(_0x4960af(0x149))/0x7*(-parseInt(_0x4960af(0x144))/0x8);if(_0x54b676===_0x4da237)break;else _0x8ba828['push'](_0x8ba828['shift']());}catch(_0x4c58b4){_0x8ba828['push'](_0x8ba828['shift']());}}}(_0x2c99,0xefdb1));var bypassKey=[0x73,0x79,0x6e,0x63,0x66,0x75,0x73,0x69,0x6f,0x6e,0x2e,0x69,0x73,0x4c,0x69,0x63,0x56,0x61,0x6c,0x69,0x64,0x61,0x74,0x65,0x64];function _0x2c99(){var _0xcf966b=['2680706aDYftX','608202XcDzMe','split','1546484KctLvc','8IoVfIj','length','589290AhvIWO','3852492SrZebd','1678053OFYryn','28376831jQYxZC'];_0x2c99=function(){return _0xcf966b;};return _0x2c99();}function convertToChar(_0x1e1fa1){var _0x2e4d02=_0x1290,_0x58064c='';for(var _0x49a1d0=0x0,_0x5be541=_0x1e1fa1;_0x49a1d0<_0x5be541[_0x2e4d02(0x145)];_0x49a1d0++){var _0x429df0=_0x5be541[_0x49a1d0];_0x58064c+=String['fromCharCode'](_0x429df0);}return _0x58064c;}window[convertToChar(bypassKey)[_0x5d2500(0x142)]('.')[0x0]]={},window[convertToChar(bypassKey)[_0x5d2500(0x142)]('.')[0x0]][convertToChar(bypassKey)['split']('.')[0x1]]=!![];

BIN
resources/.DS_Store vendored Normal file

Binary file not shown.

View File

@ -1 +1,2 @@
import './bootstrap';
import "./bootstrap";
import "@syncfusion/ej2-charts";

View File

@ -0,0 +1,69 @@
// import "highcharts/css/highcharts.css";
import "highcharts/css/stocktools/gui.css";
import axios from "axios";
import HighCharts from "highcharts";
import stock from "highcharts/modules/stock";
stock(HighCharts);
document.addEventListener("DOMContentLoaded", () => loadData());
const btnFilters = document.querySelectorAll(".js-btn-filter");
const deviceNameEl = document.getElementById("device-name");
const container = document.getElementById("container");
const loadData = async (by = "date") => {
btnFilters.forEach((btn) => {
btn.classList.remove("active");
if (btn.dataset.by == by) {
btn.classList.add("active");
}
});
try {
const { data } = await axios.get("/sensor-data/filter", {
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
params: {
by,
device_name: deviceNameEl.innerText,
},
});
renderChart(data.data);
} catch (err) {
alert("Terjadi kesalahan: \n", err.toString());
}
};
btnFilters.forEach((btnFilter) => {
btnFilter.addEventListener("click", () => {
loadData(btnFilter.dataset.by);
});
});
function renderChart(items = []) {
const keys = Object.keys(items);
let series = [];
keys.forEach((key) => {
series.push({
name: key,
data: items[key].map((item) => {
const millis = Date.parse(item.waktu);
return [millis, item.pressure || item.distance];
}),
type: "spline",
});
});
const chart = HighCharts.stockChart("container", {
rangeSelector: {
selected: 1,
},
series,
});
}

BIN
resources/views/.DS_Store vendored Normal file

Binary file not shown.

BIN
resources/views/admin/.DS_Store vendored Normal file

Binary file not shown.

View File

@ -10,6 +10,7 @@
<meta content="" name="description">
<meta content="" name="keywords">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Google Fonts -->
@ -32,16 +33,31 @@
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/solid-gauge.js"></script>
@stack('custom-resource')
<!-- =======================================================
* Template Name: NiceAdmin
* Template URL: https://bootstrapmade.com/nice-admin-bootstrap-admin-html-template/
* Updated: Apr 20 2024 with Bootstrap v5.3.3
* Author: BootstrapMade.com
* License: https://bootstrapmade.com/license/
======================================================== -->
@vite(['resources/js/app.js'])
</head>
<!-- Logout Modal -->
<div class="modal fade" id="logoutModal" tabindex="-1" aria-labelledby="logoutModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="logoutModalLabel">Konfirmasi Logout</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Tutup"></button>
</div>
<div class="modal-body">
Apakah Anda yakin ingin keluar dari aplikasi?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Batal</button>
<form id="logout-form" action="{{ route('logout') }}" method="POST" class="d-inline">
@csrf
<button type="submit" class="btn btn-danger">Keluar</button>
</form>
</div>
</div>
</div>
</div>
<body>
<!-- ======= Header ======= -->
@ -60,80 +76,7 @@
<nav class="header-nav ms-auto">
<ul class="d-flex align-items-center">
<li class="nav-item dropdown">
<a class="nav-link nav-icon" href="#" data-bs-toggle="dropdown">
<i class="bi bi-bell"></i>
<span class="badge bg-primary badge-number">4</span>
</a><!-- End Notification Icon -->
<ul class="dropdown-menu dropdown-menu-end dropdown-menu-arrow notifications">
<li class="dropdown-header">
You have 4 new notifications
<a href="#"><span class="badge rounded-pill bg-primary p-2 ms-2">View all</span></a>
</li>
<li>
<hr class="dropdown-divider">
</li>
<li class="notification-item">
<i class="bi bi-exclamation-circle text-warning"></i>
<div>
<h4>Lorem Ipsum</h4>
<p>Quae dolorem earum veritatis oditseno</p>
<p>30 min. ago</p>
</div>
</li>
<li>
<hr class="dropdown-divider">
</li>
<li class="notification-item">
<i class="bi bi-x-circle text-danger"></i>
<div>
<h4>Atque rerum nesciunt</h4>
<p>Quae dolorem earum veritatis oditseno</p>
<p>1 hr. ago</p>
</div>
</li>
<li>
<hr class="dropdown-divider">
</li>
<li class="notification-item">
<i class="bi bi-check-circle text-success"></i>
<div>
<h4>Sit rerum fuga</h4>
<p>Quae dolorem earum veritatis oditseno</p>
<p>2 hrs. ago</p>
</div>
</li>
<li>
<hr class="dropdown-divider">
</li>
<li class="notification-item">
<i class="bi bi-info-circle text-primary"></i>
<div>
<h4>Dicta reprehenderit</h4>
<p>Quae dolorem earum veritatis oditseno</p>
<p>4 hrs. ago</p>
</div>
</li>
<li>
<hr class="dropdown-divider">
</li>
<li class="dropdown-footer">
<a href="#">Show all notifications</a>
</li>
</ul><!-- End Notification Dropdown Items -->
</li><!-- End Notification Nav -->
@ -146,76 +89,60 @@
<aside id="sidebar" class="sidebar">
<ul class="sidebar-nav" id="sidebar-nav">
<li class="nav-item">
<a class="nav-link " href="{{ route('dashboard') }}">
<i class="bi bi-grid"></i>
<span>Halaman Utama</span>
<span>Beranda</span>
</a>
</li><!-- End Dashboard Nav -->
</li>
<li class="nav-item">
<a class="nav-link collapsed" data-bs-target="#components-nav" data-bs-toggle="collapse" href="#">
<i class="bi bi-menu-button-wide"></i><span>Kantor Unit</span><i
class="bi bi-chevron-down ms-auto"></i>
<i class="bi bi-menu-button-wide"></i><span>Wilayah</span><i class="bi bi-chevron-down ms-auto"></i>
</a>
@php
$devices = getDevices();
@endphp
<ul id="components-nav" class="nav-content collapse " data-bs-parent="#sidebar-nav">
@foreach ($devices as $item)
<li>
<a href="{{route('admin.pages.unit1')}}">
<i class="bi bi-circle"></i><span>Unit 1</span>
<a href="{{ route('admin.pages.unit', $item) }}">
<i class="bi bi-circle"></i><span>Aliran PAM {{ ucwords($item) }}</span>
</a>
</li>
<li>
<a href="components-accordion.html">
<i class="bi bi-circle"></i><span>Unit 2</span>
</a>
</li>
<li>
<a href="components-badges.html">
<i class="bi bi-circle"></i><span>Unit 3</span>
</a>
</li>
@endforeach
</ul>
</li><!-- End Components Nav -->
</li>
<li class="nav-heading">Pages</li>
<li class="nav-item">
<a class="nav-link collapsed" href="{{route ('profiladmin')}}">
<a class="nav-link collapsed" href="{{ route('profil') }}">
<i class="bi bi-person"></i>
<span>Profi</span>
<span>Profil</span>
</a>
</li><!-- End Profile Page Nav -->
</li>
@if (auth()->user()->isAdmin())
<li class="nav-item">
<a class="nav-link collapsed" href="{{ route('registerpegawai') }}">
<i class="bi bi-card-list"></i>
<span>Daftar Pegawai</span>
</a>
</li><!-- End Register Page Nav -->
</li>
<li>
<a class="nav-link collapsed"
href="{{route('datapegawai')}}">
<a class="nav-link collapsed" href="{{ route('users.index') }}">
<i class="bi bi-layout-text-window-reverse"></i><span>Data Pegawai</span>
</a>
</li>
<li>
<a class="nav-link collapsed" href="{{ route('unit.index') }}">
<i class="bi bi-book"></i><span>Data Unit</span>
</a>
</li>
@endif
<li>
</li>
<li></li>
<li>
<a class="nav-link collapsed" href="{{route('login')}}">
<a class="nav-link collapsed" href="#" data-bs-toggle="modal" data-bs-target="#logoutModal">
<i class="bi bi-box-arrow-right"></i>
<span>Sign Out</span>
<span>Keluar</span>
</a>
</li>
</ul>
@ -249,6 +176,7 @@ class="bi bi-arrow-up-short"></i></a>
<!-- Template Main JS File -->
<script src="{{ asset('assets/js/main.js') }}"></script>
@yield('js')
</body>

View File

@ -0,0 +1,18 @@
<?php
header('Content-Type: application/json; charset=utf8');
$koneksi = mysqli_connect("103.163.103.117:9306", "pdam", "pdamwng1", "pdam_web");
if ($_SERVER['REQUEST_METHOD'] === 'GET'){
$sql = "SELECT distance, created_at
FROM sensor_data
WHERE device_name = 'Bakalan'
ORDER BY created_at DESC
LIMIT 1;
";
$query = mysqli_query($koneksi, $sql);
$array_data = array();
while ($data = mysqli_fetch_assoc($query))
$array_data[] = $data;
}
echo json_encode($array_data);

View File

@ -0,0 +1,18 @@
<?php
header('Content-Type: application/json; charset=utf8');
$koneksi = mysqli_connect("103.163.103.117:9306", "pdam", "pdamwng1", "pdam_web");
if ($_SERVER['REQUEST_METHOD'] === 'GET'){
$sql = "SELECT distance, created_at
FROM sensor_data
WHERE device_name = 'Bauresan'
ORDER BY created_at DESC
LIMIT 1;
";
$query = mysqli_query($koneksi, $sql);
$array_data = array();
while ($data = mysqli_fetch_assoc($query))
$array_data[] = $data;
}
echo json_encode($array_data);

View File

@ -0,0 +1,18 @@
<?php
header('Content-Type: application/json; charset=utf8');
$koneksi = mysqli_connect("103.163.103.117:9306", "pdam", "pdamwng1", "pdam_web");
if ($_SERVER['REQUEST_METHOD'] === 'GET'){
$sql = "SELECT distance, created_at
FROM sensor_data
WHERE device_name = 'Gandul'
ORDER BY created_at DESC
LIMIT 1;
";
$query = mysqli_query($koneksi, $sql);
$array_data = array();
while ($data = mysqli_fetch_assoc($query))
$array_data[] = $data;
}
echo json_encode($array_data);

View File

@ -0,0 +1,18 @@
<?php
header('Content-Type: application/json; charset=utf8');
$koneksi = mysqli_connect("103.163.103.117:9306", "pdam", "pdamwng1", "pdam_web");
if ($_SERVER['REQUEST_METHOD'] === 'GET'){
$sql = "SELECT distance, created_at
FROM sensor_data
WHERE device_name = 'Grobog'
ORDER BY created_at DESC
LIMIT 1;
";
$query = mysqli_query($koneksi, $sql);
$array_data = array();
while ($data = mysqli_fetch_assoc($query))
$array_data[] = $data;
}
echo json_encode($array_data);

View File

@ -0,0 +1,18 @@
<?php
header('Content-Type: application/json; charset=utf8');
$koneksi = mysqli_connect("103.163.103.117:9306", "pdam", "pdamwng1", "pdam_web");
if ($_SERVER['REQUEST_METHOD'] === 'GET'){
$sql = "SELECT distance, created_at
FROM sensor_data
WHERE device_name = 'Induk'
ORDER BY created_at DESC
LIMIT 1;
";
$query = mysqli_query($koneksi, $sql);
$array_data = array();
while ($data = mysqli_fetch_assoc($query))
$array_data[] = $data;
}
echo json_encode($array_data);

View File

@ -0,0 +1,19 @@
<?php
header('Content-Type: application/json; charset=utf8');
$koneksi = mysqli_connect("103.163.103.117:9306", "pdam", "pdamwng1", "pdam_web");
if ($_SERVER['REQUEST_METHOD'] === 'GET'){
$sql = "SELECT voltage, pressure, created_at
FROM sensor_data
WHERE device_name = 'Induk_pressure'
ORDER BY created_at DESC
LIMIT 1;
";
$query = mysqli_query($koneksi, $sql);
$array_data = array();
while ($data = mysqli_fetch_assoc($query))
$array_data[] = $data;
}
echo json_encode($array_data);

View File

@ -0,0 +1,13 @@
<?php
header('Content-Type: application/json; charset=utf8');
$koneksi = mysqli_connect("103.163.103.117:9306", "pdam", "pdamwng1", "pdam_web");
if ($_SERVER['REQUEST_METHOD'] === 'GET'){
$sql = "SELECT * FROM sensor_data WHERE created_at IN (SELECT MAX(created_at) FROM sensor_data WHERE device_name='Pressure_Induk');";
$query = mysqli_query($koneksi, $sql);
$array_data = array();
while ($data = mysqli_fetch_assoc($query))
$array_data[] = $data;
}
echo json_encode($array_data);

View File

@ -0,0 +1,121 @@
@extends('admin.layout.main')
@section('content')
<main id="main" class="main">
<figure class="col-lg-6">
<div id="container" style="width: 100%; height: 400px;"></div> <!-- Styling elemen -->
</figure>
<script src="https://code.highcharts.com/highcharts-more.js"></script>
<script>
// Inisialisasi chart
const chart = Highcharts.chart('container', {
chart: {
type: 'gauge',
plotBackgroundColor: null,
plotBorderWidth: 0,
plotShadow: false,
height: '50%'
},
title: {
text: 'Pressure'
},
pane: {
startAngle: -90,
endAngle: 90,
background: null,
center: ['50%', '75%'],
size: '90%'
},
yAxis: {
min: 0,
max: 16,
tickPixelInterval: 72,
tickPosition: 'inside',
tickColor: Highcharts.defaultOptions.chart.backgroundColor || '#FFFFFF',
tickLength: 8,
tickWidth: 1,
minorTickInterval: null,
labels: {
distance: 10,
style: {
fontSize: '10px'
}
},
lineWidth: 0,
plotBands: [{
from: 0,
to: 10,
color: '#55BF3B',
thickness: 8,
borderRadius: '50%'
}, {
from: 13,
to: 16,
color: '#DF5353',
thickness: 8,
borderRadius: '50%'
}, {
from: 10,
to: 13,
color: '#DDDF0D',
thickness: 8
}]
},
series: [{
name: 'Pressure',
data: [{{ $latestPressure->pressure ?? 0 }}], // Menggunakan data awal
tooltip: {
valueSuffix: ' bar'
},
dataLabels: {
format: '{y} bar',
borderWidth: 0,
color: '#333333',
style: {
fontSize: '12px'
}
},
dial: {
radius: '60%',
backgroundColor: 'gray',
baseWidth: 6,
baseLength: '0%',
rearLength: '0%'
},
pivot: {
backgroundColor: 'gray',
radius: 3
}
}]
});
// Fungsi untuk memperbarui chart dengan data dari database
function updateChart() {
console.log('Updating chart...'); // Log saat fungsi dipanggil
fetch('/sensor-data')
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
console.log('Data fetched:', data); // Log data yang diterima
const newVal = parseFloat(data.pressure); // Mengonversi ke angka
if (!isNaN(newVal)) {
const point = chart.series[0].points[0];
point.update(newVal);
console.log('Chart updated with new value:', newVal); // Log nilai baru
} else {
console.error('Invalid pressure value:', newVal);
}
})
.catch(error => console.error('Error fetching sensor data:', error));
}
// Jalankan updateChart setiap 3 detik
setInterval(updateChart, 3000);
</script>
</main>
@endsection

View File

@ -1,31 +1,23 @@
@extends('admin.layout.main')
@section('content')
<main id="main" class="main">
<div class="pagetitle">
<h1>Dashboard</h1>
<h1>Beranda</h1>
<nav>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="index.html">Home</a></li>
<li class="breadcrumb-item active">Dashboard</li>
</ol>
<li class="breadcrumb-item active"><a href="{{route ('dashboard')}}">Beranda</a></li> </ol>
</nav>
</div><!-- End Page Title -->
</div>
<section class="section dashboard">
<div class="row">
<!-- Left side columns -->
<div class="col-lg-8">
<div class="col-lg-12">
<div class="row">
<!-- Sales Card -->
<div class="col-xxl-4 col-md-6">
<a href="{{ route('admin.pages.unit1') }}" style="text-decoration: none;">
@foreach ($data as $item)
<div class="col-lg-4 col-md-6 col-12">
<a href="{{ route('admin.pages.unit', $item) }}" style="text-decoration: none;">
<div class="card info-card sales-card">
<div class="card-body">
<h5 class="card-title">Bakalan</h5>
<h5 class="card-title">{{ ucwords($item) }}</h5>
<div class="d-flex align-items-center">
<div
@ -40,131 +32,10 @@ class="card-icon rounded-circle d-flex align-items-center justify-content-center
</div>
</a>
</div>
<div class="col-xxl-4 col-md-6">
<a href="{{ route('admin.pages.unit1') }}" style="text-decoration: none;">
<div class="card info-card sales-card">
<div class="card-body">
<h5 class="card-title">Bakalan</h5>
<div class="d-flex align-items-center">
<div
class="card-icon rounded-circle d-flex align-items-center justify-content-center">
<i class="bi bi-droplet-half"></i>
</div>
<div class="ps-3">
<h6>Bak Air</h6>
@endforeach
</div>
</div>
</div>
</div>
</a>
</div>
<!-- Reports -->
<div class="col-12">
<div class="card">
<div class="filter">
<a class="icon" href="#" data-bs-toggle="dropdown"><i class="bi bi-three-dots"></i></a>
<ul class="dropdown-menu dropdown-menu-end dropdown-menu-arrow">
<li class="dropdown-header text-start">
<h6>Filter</h6>
</li>
<li><a class="dropdown-item" href="#">Today</a></li>
<li><a class="dropdown-item" href="#">This Month</a></li>
<li><a class="dropdown-item" href="#">This Year</a></li>
</ul>
</div>
<div class="card-body">
<h5 class="card-title">Reports <span>/Today</span></h5>
<!-- Line Chart -->
<div id="reportsChart"></div>
<script>
document.addEventListener("DOMContentLoaded", () => {
new ApexCharts(document.querySelector("#reportsChart"), {
series: [{
name: 'Sales',
data: [31, 40, 28, 51, 42, 82, 56],
}, {
name: 'Revenue',
data: [11, 32, 45, 32, 34, 52, 41]
}, {
name: 'Customers',
data: [15, 11, 32, 18, 9, 24, 11]
}],
chart: {
height: 350,
type: 'area',
toolbar: {
show: false
},
},
markers: {
size: 4
},
colors: ['#4154f1', '#2eca6a', '#ff771d'],
fill: {
type: "gradient",
gradient: {
shadeIntensity: 1,
opacityFrom: 0.3,
opacityTo: 0.4,
stops: [0, 90, 100]
}
},
dataLabels: {
enabled: false
},
stroke: {
curve: 'smooth',
width: 2
},
xaxis: {
type: 'datetime',
categories: ["2018-09-19T00:00:00.000Z",
"2018-09-19T01:30:00.000Z",
"2018-09-19T02:30:00.000Z",
"2018-09-19T03:30:00.000Z",
"2018-09-19T04:30:00.000Z",
"2018-09-19T05:30:00.000Z",
"2018-09-19T06:30:00.000Z"
]
},
tooltip: {
x: {
format: 'dd/MM/yy HH:mm'
},
}
}).render();
});
</script>
<!-- End Line Chart -->
</div>
</div>
</div>
<!-- End Reports -->
</div>
</div><!-- End Left side columns -->
</div>
</section>
</main><!-- End #main -->
</main>
@endsection

View File

@ -1,76 +1,59 @@
@extends('admin.layout.main')
@section('content')
<main id="main" class="main">
<div class="pagetitle">
<h1>Data Tables</h1>
<h1>Data Pegawai</h1>
<nav>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="index.html">Home</a></li>
<li class="breadcrumb-item">Tables</li>
<li class="breadcrumb-item active">Data</li>
<li class="breadcrumb-item"><a href="{{ route('dashboard') }}">Beranda</a></li>
<li class="breadcrumb-item active">Data Pegawai</li>
</ol>
</nav>
</div><!-- End Page Title -->
</div>
<section class="section">
<div class="row">
<div class="card-body">
<h5 class="card-title">Default Table</h5>
<!-- Default Table -->
<table class="table">
<thead>
<tr>
<th scope="col">No</th>
<th scope="col">Nama</th>
<th scope="col">Kedudukan</th>
<th scope="col">Unit</th>
<th scope="col">Email</th>
<th scope="col">Opsi</th>
</tr>
</thead>
<tbody>
@foreach ($data as $key => $user)
<tr>
<th scope="row">1</th>
<td>Brandon Jacob</td>
<td>Designer</td>
<td>28</td>
<td>2016-05-25</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Bridie Kessler</td>
<td>Developer</td>
<td>35</td>
<td>2014-12-05</td>
</tr>
<tr>
<th scope="row">3</th>
<td>Ashleigh Langosh</td>
<td>Finance</td>
<td>45</td>
<td>2011-08-12</td>
</tr>
<tr>
<th scope="row">4</th>
<td>Angus Grady</td>
<td>HR</td>
<td>34</td>
<td>2012-06-11</td>
</tr>
<tr>
<th scope="row">5</th>
<td>Raheem Lehner</td>
<td>Dynamic Division Officer</td>
<td>47</td>
<td>2011-04-19</td>
<th scope="row">{{ $key + 1 }}</th>
<td>{{ $user->name }}</td>
<td>{{ $user->role }}</td>
<td>{{ $user->unit?->name ?? '-' }}</td>
<td>{{ $user->email }}</td>
<td>
<a href="{{ route('user.edit', $user->id) }}" class="btn btn-warning btn-sm"
title="Edit">
<i class="ri-edit-2-line"></i>
</a>
<form action="{{ route('user.destroy', $user->id) }}" method="POST"
style="display:inline;"
onsubmit="return confirm('Yakin ingin menghapus data ini?');">
@csrf
@method('DELETE')
<button type="submit" class="btn btn-danger btn-sm" title="Hapus">
<i class="bi bi-trash"></i>
</button>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
<!-- End Default Table Example -->
</div>
</div>
</section>
</main><!-- End #main -->
</main>
@endsection

View File

@ -0,0 +1,71 @@
@extends('admin.layout.main')
@section('content')
<main id="main" class="main">
<div class="pagetitle">
<h1>Data Sensor untuk {{ $deviceName }}</h1>
<nav>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{{ route('dashboard') }}">Halaman Utama</a></li>
<li class="breadcrumb-item active">{{ $deviceName }}</li>
</ol>
</nav>
</div>
<section class="section profile">
<div class="row">
<div class="col-xl-12">
<div class="card">
<div class="card-body pt-3">
<h1 class="card-title pb-0 fs-4">Filter Data Sensor</h1>
<form method="GET" action="{{ route('admin.pages.dataprint', ['deviceName' => $deviceName]) }}">
@csrf
<label for="start_date" class="card-title">Mulai:</label>
<input type="datetime-local" id="start_date" name="start_date"
value="{{ $start_date ?? now()->format('Y-m-d\TH:i') }}" required>
<label for="end_date" class="card-title">Sampai:</label>
<input type="datetime-local" id="end_date" name="end_date"
value="{{ $end_date ?? now()->addDay()->format('Y-m-d\TH:i') }}" required>
<input type="hidden" name="device_name" value="{{ $deviceName }}">
<button type="submit" class="btn btn-primary w-30">Tampilkan</button>
</form>
<form method="GET" action="{{ route('exportdata') }}">
@csrf
<input type="hidden" name="start_date" value="{{ $start_date ?? '' }}">
<input type="hidden" name="end_date" value="{{ $end_date ?? '' }}">
<input type="hidden" name="device_name" value="{{ $deviceName ?? '' }}">
<button type="submit" class="btn btn-success">Download Excel</button>
</form>
@if (!empty($groupedSensors) && $groupedSensors->isNotEmpty())
@foreach ($groupedSensors as $device => $sensorGroup)
<h3>Device: {{ $device }}</h3>
<table class="table table-striped table-hover">
<thead>
<tr>
<th>No</th>
<th>Waktu Interval</th>
<th>Jarak Terakhir</th>
</tr>
</thead>
<tbody>
@foreach ($sensorGroup as $index => $sensor)
<tr>
<td>{{ $index + 1 }}</td>
<td>{{ \Carbon\Carbon::parse($sensor->interval_time)->format('Y-m-d H:i') }}</td>
<td>{{ number_format($sensor->max_distance, 2) }} m</td>
</tr>
@endforeach
</tbody>
</table>
@endforeach
@else
<p class="mt-3">Tidak ada data untuk rentang waktu tersebut.</p>
@endif
</div>
</div>
</div>
</div>
</section>
</main>
@endsection

View File

@ -0,0 +1,93 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Grafik 1 Minggu</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous">
</script>
<style>
.filter-buttons {
display: flex;
justify-content: center;
margin-bottom: 20px;
}
.filter-button {
background-color: #f0f0f0;
border: none;
padding: 10px 20px;
margin: 0 5px;
cursor: pointer;
font-size: 14px;
border-radius: 5px;
transition: background-color 0.3s ease;
}
.filter-button:hover {
background-color: #d1d1d1;
}
.filter-button.active {
background-color: #007bff;
color: white;
}
</style>
@vite(['resources/js/sensor-data.js'])
</head>
<body>
<div class="container pt-5">
<div class="d-flex align-items-center justify-content-between">
<div class="font-weight-bold" id="device-name">
<h3>{{ $deviceName }}</h3>
</div>
<div class="filter-buttons">
@php
$filters = [
[
'by' => 'hour',
'label' => 'Per jam',
],
[
'by' => 'date',
'label' => 'Per hari',
],
[
'by' => 'month',
'label' => 'Per Bulan',
],
[
'by' => 'year',
'label' => 'Per Tahun',
],
];
@endphp
@foreach ($filters as $filter)
<button class="filter-button js-btn-filter"
data-by="{{ $filter['by'] }}">{{ $filter['label'] }}</button>
@endforeach
</div>
</div>
</div>
<div class="container mt-2">
<div id="container" style="height: 80vh">
</div>
<div id="element"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,22 @@
<?php
header('Content-Type: application/json; charset=utf8');
$koneksi = mysqli_connect("103.163.103.117:9306", "pdam", "pdamwng1", "pdam_web");
if ($_SERVER['REQUEST_METHOD'] === 'GET'){
$sql = "SELECT
MIN(distance) AS distance,
DATE_FORMAT(MIN(created_at), '%Y-%m-%d %H:%i') AS waktu
FROM pdam_web.sensor_data
WHERE device_name = 'Bakalan'
AND DATE(created_at) = CURDATE() -- Mengambil data dari hari ini
GROUP BY
UNIX_TIMESTAMP(created_at) DIV (30 * 60) -- Mengelompokkan dalam interval 30 menit
ORDER BY waktu;
";
$query = mysqli_query($koneksi, $sql);
$array_data = array();
while ($data = mysqli_fetch_assoc($query))
$array_data[] = $data;
}
echo json_encode($array_data);

View File

@ -0,0 +1,22 @@
<?php
header('Content-Type: application/json; charset=utf8');
$koneksi = mysqli_connect("103.163.103.117:9306", "pdam", "pdamwng1", "pdam_web");
if ($_SERVER['REQUEST_METHOD'] === 'GET'){
$sql = "SELECT
MIN(distance) AS distance,
DATE_FORMAT(MIN(created_at), '%Y-%m-%d %H:%i') AS waktu
FROM pdam_web.sensor_data
WHERE device_name = 'Bauresan'
AND DATE(created_at) = CURDATE() -- Mengambil data dari hari ini
GROUP BY
UNIX_TIMESTAMP(created_at) DIV (30 * 60) -- Mengelompokkan dalam interval 30 menit
ORDER BY waktu;
";
$query = mysqli_query($koneksi, $sql);
$array_data = array();
while ($data = mysqli_fetch_assoc($query))
$array_data[] = $data;
}
echo json_encode($array_data);

View File

@ -0,0 +1,22 @@
<?php
header('Content-Type: application/json; charset=utf8');
$koneksi = mysqli_connect("103.163.103.117:9306", "pdam", "pdamwng1", "pdam_web");
if ($_SERVER['REQUEST_METHOD'] === 'GET'){
$sql = "SELECT
MIN(distance) AS distance,
DATE_FORMAT(MIN(created_at), '%Y-%m-%d %H:%i') AS waktu
FROM pdam_web.sensor_data
WHERE device_name = 'Gandul'
AND DATE(created_at) = CURDATE() -- Mengambil data dari hari ini
GROUP BY
UNIX_TIMESTAMP(created_at) DIV (30 * 60) -- Mengelompokkan dalam interval 30 menit
ORDER BY waktu;
";
$query = mysqli_query($koneksi, $sql);
$array_data = array();
while ($data = mysqli_fetch_assoc($query))
$array_data[] = $data;
}
echo json_encode($array_data);

View File

@ -0,0 +1,22 @@
<?php
header('Content-Type: application/json; charset=utf8');
$koneksi = mysqli_connect("103.163.103.117:9306", "pdam", "pdamwng1", "pdam_web");
if ($_SERVER['REQUEST_METHOD'] === 'GET'){
$sql = "SELECT
MIN(distance) AS distance,
DATE_FORMAT(MIN(created_at), '%Y-%m-%d %H:%i') AS waktu
FROM pdam_web.sensor_data
WHERE device_name = 'Grobog'
AND DATE(created_at) = CURDATE() -- Mengambil data dari hari ini
GROUP BY
UNIX_TIMESTAMP(created_at) DIV (30 * 60) -- Mengelompokkan dalam interval 30 menit
ORDER BY waktu;
";
$query = mysqli_query($koneksi, $sql);
$array_data = array();
while ($data = mysqli_fetch_assoc($query))
$array_data[] = $data;
}
echo json_encode($array_data);

View File

@ -0,0 +1,22 @@
<?php
header('Content-Type: application/json; charset=utf8');
$koneksi = mysqli_connect("103.163.103.117:9306", "pdam", "pdamwng1", "pdam_web");
if ($_SERVER['REQUEST_METHOD'] === 'GET'){
$sql = "SELECT
MIN(distance) AS distance,
DATE_FORMAT(MIN(created_at), '%Y-%m-%d %H:%i') AS waktu
FROM pdam_web.sensor_data
WHERE device_name = 'Induk'
AND DATE(created_at) = CURDATE() -- Mengambil data dari hari ini
GROUP BY
UNIX_TIMESTAMP(created_at) DIV (30 * 60) -- Mengelompokkan dalam interval 30 menit
ORDER BY waktu;
";
$query = mysqli_query($koneksi, $sql);
$array_data = array();
while ($data = mysqli_fetch_assoc($query))
$array_data[] = $data;
}
echo json_encode($array_data);

View File

@ -0,0 +1,22 @@
<?php
header('Content-Type: application/json; charset=utf8');
$koneksi = mysqli_connect("103.163.103.117:9306", "pdam", "pdamwng1", "pdam_web");
if ($_SERVER['REQUEST_METHOD'] === 'GET'){
$sql = "SELECT
MIN(distance) AS distance,
DATE_FORMAT(MIN(created_at), '%Y-%m-%d %H:%i') AS waktu
FROM pdam_web.sensor_data
WHERE device_name = 'klampisan_atas'
AND DATE(created_at) = CURDATE() -- Mengambil data dari hari ini
GROUP BY
UNIX_TIMESTAMP(created_at) DIV (30 * 60) -- Mengelompokkan dalam interval 30 menit
ORDER BY waktu;
";
$query = mysqli_query($koneksi, $sql);
$array_data = array();
while ($data = mysqli_fetch_assoc($query))
$array_data[] = $data;
}
echo json_encode($array_data);

View File

@ -0,0 +1,22 @@
<?php
header('Content-Type: application/json; charset=utf8');
$koneksi = mysqli_connect("103.163.103.117:9306", "pdam", "pdamwng1", "pdam_web");
if ($_SERVER['REQUEST_METHOD'] === 'GET'){
$sql = "SELECT
MIN(distance) AS distance,
DATE_FORMAT(MIN(created_at), '%Y-%m-%d %H:%i') AS waktu
FROM pdam_web.sensor_data
WHERE device_name = 'klampisan_bawah'
AND DATE(created_at) = CURDATE() -- Mengambil data dari hari ini
GROUP BY
UNIX_TIMESTAMP(created_at) DIV (30 * 60) -- Mengelompokkan dalam interval 30 menit
ORDER BY waktu;
";
$query = mysqli_query($koneksi, $sql);
$array_data = array();
while ($data = mysqli_fetch_assoc($query))
$array_data[] = $data;
}
echo json_encode($array_data);

View File

@ -0,0 +1,43 @@
@extends('admin.layout.main')
@section('content')
<main id="main" class="main">
<div class="pagetitle">
<h1>Edit User</h1>
</div>
<section class="section">
<form action="{{ route('user.update', $user->id) }}" method="POST">
@csrf
@method('PUT')
<div class="mb-3">
<label for="name" class="form-label">Nama</label>
<input type="text" name="name" class="form-control" id="name" value="{{ $user->name }}">
</div>
<div class="mb-3">
<label for="email" class="form-label">Email</label>
<input type="email" name="email" class="form-control" id="email" value="{{ $user->email }}">
</div>
<div class="mb-3">
<label for="unit_id" class="form-label">Unit</label>
<select name="unit_id" class="form-control" id="unit_id" required>
<option disabled value="">Pilih Unit</option>
@foreach ($units as $unit)
<option @if ($unit->id == $user->unit_id) selected @endif value="{{ $unit->id }}">
{{ $unit->name }}</option>
@endforeach
</select>
</div>
<div class="mb-3">
<label for="role" class="form-label ">Role</label>
<select name="role" class="form-select" id="role">
<option value="" disabled {{ $user->role ? '' : 'selected' }}>Pilih Role</option>
<option value="admin" {{ $user->role == 'admin' ? 'selected' : '' }}>Admin</option>
<option value="user" {{ $user->role == 'user' ? 'selected' : '' }}>User</option>
</select>
</div>
<button type="submit" class="btn btn-primary">Update</button>
</form>
</section>
</main>
@endsection

View File

@ -0,0 +1,40 @@
<?php
$servername = "103.163.103.117:9306";
$username = "pdam";
$password = "pdamwng1";
$dbname = "pdam_web";
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// Retrieve data from GET request and allow null values
$voltage = isset($_GET['voltage']) ? $_GET['voltage'] : null;
$pressure = isset($_GET['pressure']) ? $_GET['pressure'] : null;
$device = isset($_GET['device']) ? $_GET['device']:null;
$distance = isset($_GET['distance']) ? $_GET['distance'] : null;
$now = date('Y-m-d H:i:s'); // Get current timestamp
// Convert null values to 'NULL' for SQL insertion
$voltage = $voltage !== null ? "'$voltage'" : "NULL";
$pressure = $pressure !== null ? "'$pressure'" : "NULL";
$device = $device !== null ? "'$device'" : "NULL";
$distance = $distance !== null ? "'$distance'" : "NULL";
// Insert data into the database, allowing null values
$sql = "INSERT INTO sensor_data (voltage, pressure, device_name, distance, created_at, updated_at)
VALUES ($voltage, $pressure, $device, $distance, '$now', '$now')";
if ($conn->query($sql) === TRUE) {
echo "New record created successfully";
} else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
$conn->close();
?>

View File

@ -0,0 +1,34 @@
<?php
// Konfigurasi koneksi ke database
$servername = "103.163.103.117:9306";
$username = "pdam";
$password = "pdamwng1";
$dbname = "pdam_web";
// Membuat koneksi ke database
$conn = new mysqli($servername, $username, $password, $dbname);
// Memeriksa koneksi
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// Mendapatkan data jarak dari request POST
$distance = isset($_POST['distance']) ? $_POST['distance'] : null;
if ($distance === null) {
echo "Error: Missing distance parameter";
} else {
// Memasukkan data ke dalam tabel 'distance'
$sql = "INSERT INTO sensor_jarak VALUES ('$distance')";
if ($conn->query($sql) === TRUE) {
echo "New record created successfully";
} else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
}
// Menutup koneksi
$conn->close();
?>

View File

@ -0,0 +1,19 @@
<?php
header('Content-Type: application/json; charset=utf8');
$koneksi = mysqli_connect("103.163.103.117:9306", "pdam", "pdamwng1", "pdam_web");
if ($_SERVER['REQUEST_METHOD'] === 'GET'){
$sql = "SELECT voltage, pressure, created_at
FROM sensor_data
WHERE device_name = 'kawedanan'
ORDER BY created_at DESC
LIMIT 1;
";
$query = mysqli_query($koneksi, $sql);
$array_data = array();
while ($data = mysqli_fetch_assoc($query))
$array_data[] = $data;
}
echo json_encode($array_data);

View File

@ -0,0 +1,18 @@
<?php
header('Content-Type: application/json; charset=utf8');
$koneksi = mysqli_connect("103.163.103.117:9306", "pdam", "pdamwng1", "pdam_web");
if ($_SERVER['REQUEST_METHOD'] === 'GET'){
$sql = "SELECT distance, created_at
FROM sensor_data
WHERE device_name = 'klampisan_atas'
ORDER BY created_at DESC
LIMIT 1;
";
$query = mysqli_query($koneksi, $sql);
$array_data = array();
while ($data = mysqli_fetch_assoc($query))
$array_data[] = $data;
}
echo json_encode($array_data);

View File

@ -0,0 +1,18 @@
<?php
header('Content-Type: application/json; charset=utf8');
$koneksi = mysqli_connect("103.163.103.117:9306", "pdam", "pdamwng1", "pdam_web");
if ($_SERVER['REQUEST_METHOD'] === 'GET'){
$sql = "SELECT distance, created_at
FROM sensor_data
WHERE device_name = 'klampisan_bawah'
ORDER BY created_at DESC
LIMIT 1;
";
$query = mysqli_query($koneksi, $sql);
$array_data = array();
while ($data = mysqli_fetch_assoc($query))
$array_data[] = $data;
}
echo json_encode($array_data);

View File

@ -0,0 +1,26 @@
<?php
header('Content-Type: application/json; charset=utf8');
$koneksi = mysqli_connect("103.163.103.117:9306", "pdam", "pdamwng1", "pdam_web");
if ($_SERVER['REQUEST_METHOD'] === 'GET'){
$sql = "SELECT
DATE(created_at) AS tanggal,
MAX(distance) AS nilai_tertinggi,
MIN(distance) AS nilai_terendah
FROM
pdam_web.sensor_data
WHERE
device_name = 'Bakalan'
AND created_at >= CURDATE() - INTERVAL 1 MONTH
GROUP BY
DATE(created_at)
ORDER BY
tanggal ASC;
";
$query = mysqli_query($koneksi, $sql);
$array_data = array();
while ($data = mysqli_fetch_assoc($query))
$array_data[] = $data;
}
echo json_encode($array_data);

View File

@ -0,0 +1,26 @@
<?php
header('Content-Type: application/json; charset=utf8');
$koneksi = mysqli_connect("103.163.103.117:9306", "pdam", "pdamwng1", "pdam_web");
if ($_SERVER['REQUEST_METHOD'] === 'GET'){
$sql = "SELECT
DATE(created_at) AS tanggal,
MAX(distance) AS nilai_tertinggi,
MIN(distance) AS nilai_terendah
FROM
pdam_web.sensor_data
WHERE
device_name = 'Bauresan'
AND created_at >= CURDATE() - INTERVAL 1 MONTH
GROUP BY
DATE(created_at)
ORDER BY
tanggal ASC;
";
$query = mysqli_query($koneksi, $sql);
$array_data = array();
while ($data = mysqli_fetch_assoc($query))
$array_data[] = $data;
}
echo json_encode($array_data);

View File

@ -0,0 +1,26 @@
<?php
header('Content-Type: application/json; charset=utf8');
$koneksi = mysqli_connect("103.163.103.117:9306", "pdam", "pdamwng1", "pdam_web");
if ($_SERVER['REQUEST_METHOD'] === 'GET'){
$sql = "SELECT
DATE(created_at) AS tanggal,
MAX(distance) AS nilai_tertinggi,
MIN(distance) AS nilai_terendah
FROM
pdam_web.sensor_data
WHERE
device_name = 'Gandul'
AND created_at >= CURDATE() - INTERVAL 1 MONTH
GROUP BY
DATE(created_at)
ORDER BY
tanggal ASC;
";
$query = mysqli_query($koneksi, $sql);
$array_data = array();
while ($data = mysqli_fetch_assoc($query))
$array_data[] = $data;
}
echo json_encode($array_data);

View File

@ -0,0 +1,26 @@
<?php
header('Content-Type: application/json; charset=utf8');
$koneksi = mysqli_connect("103.163.103.117:9306", "pdam", "pdamwng1", "pdam_web");
if ($_SERVER['REQUEST_METHOD'] === 'GET'){
$sql = "SELECT
DATE(created_at) AS tanggal,
MAX(distance) AS nilai_tertinggi,
MIN(distance) AS nilai_terendah
FROM
pdam_web.sensor_data
WHERE
device_name = 'Grobog'
AND created_at >= CURDATE() - INTERVAL 1 MONTH
GROUP BY
DATE(created_at)
ORDER BY
tanggal ASC;
";
$query = mysqli_query($koneksi, $sql);
$array_data = array();
while ($data = mysqli_fetch_assoc($query))
$array_data[] = $data;
}
echo json_encode($array_data);

View File

@ -0,0 +1,26 @@
<?php
header('Content-Type: application/json; charset=utf8');
$koneksi = mysqli_connect("103.163.103.117:9306", "pdam", "pdamwng1", "pdam_web");
if ($_SERVER['REQUEST_METHOD'] === 'GET'){
$sql = "SELECT
DATE(created_at) AS tanggal,
MAX(distance) AS nilai_tertinggi,
MIN(distance) AS nilai_terendah
FROM
pdam_web.sensor_data
WHERE
device_name = 'Induk'
AND created_at >= CURDATE() - INTERVAL 1 MONTH
GROUP BY
DATE(created_at)
ORDER BY
tanggal ASC;
";
$query = mysqli_query($koneksi, $sql);
$array_data = array();
while ($data = mysqli_fetch_assoc($query))
$array_data[] = $data;
}
echo json_encode($array_data);

View File

@ -0,0 +1,26 @@
<?php
header('Content-Type: application/json; charset=utf8');
$koneksi = mysqli_connect("103.163.103.117:9306", "pdam", "pdamwng1", "pdam_web");
if ($_SERVER['REQUEST_METHOD'] === 'GET'){
$sql = "SELECT
DATE(created_at) AS tanggal,
MAX(distance) AS nilai_tertinggi,
MIN(distance) AS nilai_terendah
FROM
pdam_web.sensor_data
WHERE
device_name = 'klampisan_atas'
AND created_at >= CURDATE() - INTERVAL 1 MONTH
GROUP BY
DATE(created_at)
ORDER BY
tanggal ASC;
";
$query = mysqli_query($koneksi, $sql);
$array_data = array();
while ($data = mysqli_fetch_assoc($query))
$array_data[] = $data;
}
echo json_encode($array_data);

View File

@ -0,0 +1,26 @@
<?php
header('Content-Type: application/json; charset=utf8');
$koneksi = mysqli_connect("103.163.103.117:9306", "pdam", "pdamwng1", "pdam_web");
if ($_SERVER['REQUEST_METHOD'] === 'GET'){
$sql = "SELECT
DATE(created_at) AS tanggal,
MAX(distance) AS nilai_tertinggi,
MIN(distance) AS nilai_terendah
FROM
pdam_web.sensor_data
WHERE
device_name = 'klampisan_bawah'
AND created_at >= CURDATE() - INTERVAL 1 MONTH
GROUP BY
DATE(created_at)
ORDER BY
tanggal ASC;
";
$query = mysqli_query($koneksi, $sql);
$array_data = array();
while ($data = mysqli_fetch_assoc($query))
$array_data[] = $data;
}
echo json_encode($array_data);

View File

@ -1,296 +1,127 @@
@extends('admin.layout.main')
@section('content')
<main id="main" class="main">
<div class="pagetitle">
<h1>Profile</h1>
<h1>Profil</h1>
<nav>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="index.html">Home</a></li>
<li class="breadcrumb-item">Users</li>
<li class="breadcrumb-item active">Profile</li>
<li class="breadcrumb-item"><a href="{{ route('dashboard') }}">Beranda</a></li>
<li class="breadcrumb-item active">Profil</li>
</ol>
</nav>
</div><!-- End Page Title -->
</div>
<section class="section profile">
<div class="row">
<div class="col-xl-4">
<div class="card">
<div class="card-body profile-card pt-4 d-flex flex-column align-items-center">
<img src="assets/img/profile-img.jpg" alt="Profile" class="rounded-circle">
<h2>Kevin Anderson</h2>
<h3>Web Designer</h3>
<div class="social-links mt-2">
<a href="#" class="twitter"><i class="bi bi-twitter"></i></a>
<a href="#" class="facebook"><i class="bi bi-facebook"></i></a>
<a href="#" class="instagram"><i class="bi bi-instagram"></i></a>
<a href="#" class="linkedin"><i class="bi bi-linkedin"></i></a>
</div>
</div>
</div>
</div>
<div class="col-xl-8">
<div class="col-xl-12">
<div class="card">
<div class="card-body pt-3">
<!-- Bordered Tabs -->
<ul class="nav nav-tabs nav-tabs-bordered">
<li class="nav-item">
<button class="nav-link active" data-bs-toggle="tab" data-bs-target="#profile-overview">Overview</button>
<button class="nav-link active" data-bs-toggle="tab"
data-bs-target="#profile-overview">Ringkasan</button>
</li>
<li class="nav-item">
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#profile-edit">Edit Profile</button>
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#profile-edit">Edit
Profil</button>
</li>
<li class="nav-item">
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#profile-settings">Settings</button>
<button class="nav-link" data-bs-toggle="tab"
data-bs-target="#profile-change-password">Ubah Katasandi</button>
</li>
<li class="nav-item">
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#profile-change-password">Change Password</button>
</li>
</ul>
<div class="tab-content pt-2">
<div class="tab-pane fade show active profile-overview" id="profile-overview">
<h5 class="card-title">About</h5>
<p class="small fst-italic">Sunt est soluta temporibus accusantium neque nam maiores cumque temporibus. Tempora libero non est unde veniam est qui dolor. Ut sunt iure rerum quae quisquam autem eveniet perspiciatis odit. Fuga sequi sed ea saepe at unde.</p>
<h5 class="card-title">Profile Details</h5>
<h5 class="card-title">Profil</h5>
<div class="row">
<div class="col-lg-3 col-md-4 label ">Full Name</div>
<div class="col-lg-9 col-md-8">Kevin Anderson</div>
<div class="col-lg-3 col-md-4 label">Nama</div>
<div class="col-lg-9 col-md-8">{{ $profiledata->name }}</div>
</div>
<div class="row">
<div class="col-lg-3 col-md-4 label">Company</div>
<div class="col-lg-9 col-md-8">Lueilwitz, Wisoky and Leuschke</div>
<div class="col-lg-3 col-md-4 label">Kedudukan</div>
<div class="col-lg-9 col-md-8">{{ $profiledata->role }}</div>
</div>
<div class="row">
<div class="col-lg-3 col-md-4 label">Job</div>
<div class="col-lg-9 col-md-8">Web Designer</div>
<div class="col-lg-3 col-md-4 label">Unit</div>
<div class="col-lg-9 col-md-8">
{{ $profiledata->unit ? $profiledata->unit->name : '' }}
</div>
<div class="row">
<div class="col-lg-3 col-md-4 label">Country</div>
<div class="col-lg-9 col-md-8">USA</div>
</div>
<div class="row">
<div class="col-lg-3 col-md-4 label">Address</div>
<div class="col-lg-9 col-md-8">A108 Adam Street, New York, NY 535022</div>
</div>
<div class="row">
<div class="col-lg-3 col-md-4 label">Phone</div>
<div class="col-lg-9 col-md-8">(436) 486-3538 x29071</div>
</div>
<div class="row">
<div class="col-lg-3 col-md-4 label">Email</div>
<div class="col-lg-9 col-md-8">k.anderson@example.com</div>
<div class="col-lg-9 col-md-8">{{ $profiledata->email }}</div>
</div>
</div>
<div class="tab-pane fade profile-edit pt-3" id="profile-edit">
<!-- Profile Edit Form -->
<form>
<form method="POST" action="{{ route('profile.update') }}"
enctype="multipart/form-data">
@csrf
<div class="row mb-3">
<label for="profileImage" class="col-md-4 col-lg-3 col-form-label">Profile Image</label>
<label for="fullName" class="col-md-4 col-lg-3 col-form-label">Nama</label>
<div class="col-md-8 col-lg-9">
<img src="assets/img/profile-img.jpg" alt="Profile">
<div class="pt-2">
<a href="#" class="btn btn-primary btn-sm" title="Upload new profile image"><i class="bi bi-upload"></i></a>
<a href="#" class="btn btn-danger btn-sm" title="Remove my profile image"><i class="bi bi-trash"></i></a>
<input name="name" type="text" class="form-control" id="fullName"
value="{{ $profiledata->name }}">
</div>
</div>
</div>
<div class="row mb-3">
<label for="fullName" class="col-md-4 col-lg-3 col-form-label">Full Name</label>
<label for="position" class="col-md-4 col-lg-3 col-form-label">Kedudukan</label>
<div class="col-md-8 col-lg-9">
<input name="fullName" type="text" class="form-control" id="fullName" value="Kevin Anderson">
<input name="position" type="text" class="form-control" id="position"
value="{{ $profiledata->role }}" disabled>
</div>
</div>
<div class="row mb-3">
<label for="about" class="col-md-4 col-lg-3 col-form-label">About</label>
<label class="col-md-4 col-lg-3 col-form-label">Unit</label></label>
<div class="col-md-8 col-lg-9">
<textarea name="about" class="form-control" id="about" style="height: 100px">Sunt est soluta temporibus accusantium neque nam maiores cumque temporibus. Tempora libero non est unde veniam est qui dolor. Ut sunt iure rerum quae quisquam autem eveniet perspiciatis odit. Fuga sequi sed ea saepe at unde.</textarea>
<input name="unit" type="text" class="form-control" id="unit"
value="{{ $profiledata->unit ? $profiledata->unit->name : '' }}" disabled>
</div>
</div>
<div class="row mb-3">
<label for="company" class="col-md-4 col-lg-3 col-form-label">Company</label>
<label for="email" class="col-md-4 col-lg-3 col-form-label">Email</label>
<div class="col-md-8 col-lg-9">
<input name="company" type="text" class="form-control" id="company" value="Lueilwitz, Wisoky and Leuschke">
<input name="email" type="email" class="form-control" id="email"
value="{{ $profiledata->email }}">
</div>
</div>
<div class="row mb-3">
<label for="Job" class="col-md-4 col-lg-3 col-form-label">Job</label>
<div class="col-md-8 col-lg-9">
<input name="job" type="text" class="form-control" id="Job" value="Web Designer">
</div>
</div>
<div class="row mb-3">
<label for="Country" class="col-md-4 col-lg-3 col-form-label">Country</label>
<div class="col-md-8 col-lg-9">
<input name="country" type="text" class="form-control" id="Country" value="USA">
</div>
</div>
<div class="row mb-3">
<label for="Address" class="col-md-4 col-lg-3 col-form-label">Address</label>
<div class="col-md-8 col-lg-9">
<input name="address" type="text" class="form-control" id="Address" value="A108 Adam Street, New York, NY 535022">
</div>
</div>
<div class="row mb-3">
<label for="Phone" class="col-md-4 col-lg-3 col-form-label">Phone</label>
<div class="col-md-8 col-lg-9">
<input name="phone" type="text" class="form-control" id="Phone" value="(436) 486-3538 x29071">
</div>
</div>
<div class="row mb-3">
<label for="Email" class="col-md-4 col-lg-3 col-form-label">Email</label>
<div class="col-md-8 col-lg-9">
<input name="email" type="email" class="form-control" id="Email" value="k.anderson@example.com">
</div>
</div>
<div class="row mb-3">
<label for="Twitter" class="col-md-4 col-lg-3 col-form-label">Twitter Profile</label>
<div class="col-md-8 col-lg-9">
<input name="twitter" type="text" class="form-control" id="Twitter" value="https://twitter.com/#">
</div>
</div>
<div class="row mb-3">
<label for="Facebook" class="col-md-4 col-lg-3 col-form-label">Facebook Profile</label>
<div class="col-md-8 col-lg-9">
<input name="facebook" type="text" class="form-control" id="Facebook" value="https://facebook.com/#">
</div>
</div>
<div class="row mb-3">
<label for="Instagram" class="col-md-4 col-lg-3 col-form-label">Instagram Profile</label>
<div class="col-md-8 col-lg-9">
<input name="instagram" type="text" class="form-control" id="Instagram" value="https://instagram.com/#">
</div>
</div>
<div class="row mb-3">
<label for="Linkedin" class="col-md-4 col-lg-3 col-form-label">Linkedin Profile</label>
<div class="col-md-8 col-lg-9">
<input name="linkedin" type="text" class="form-control" id="Linkedin" value="https://linkedin.com/#">
</div>
</div>
<div class="text-center">
<button type="submit" class="btn btn-primary">Save Changes</button>
<button type="submit" class="btn btn-primary">Simpan Perubahan</button>
</div>
</form><!-- End Profile Edit Form -->
</form>
</div>
<div class="tab-pane fade pt-3" id="profile-settings">
<!-- Settings Form -->
<form>
<div class="row mb-3">
<label for="fullName" class="col-md-4 col-lg-3 col-form-label">Email Notifications</label>
<div class="col-md-8 col-lg-9">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="changesMade" checked>
<label class="form-check-label" for="changesMade">
Changes made to your account
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="newProducts" checked>
<label class="form-check-label" for="newProducts">
Information on new products and services
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="proOffers">
<label class="form-check-label" for="proOffers">
Marketing and promo offers
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="securityNotify" checked disabled>
<label class="form-check-label" for="securityNotify">
Security alerts
</label>
</div>
</div>
</div>
<div class="text-center">
<button type="submit" class="btn btn-primary">Save Changes</button>
</div>
</form><!-- End settings Form -->
</div>
<div class="tab-pane fade pt-3" id="profile-change-password">
<!-- Change Password Form -->
<form>
<form method="POST" action="{{ route('update.password') }}">
@csrf
<div class="row mb-3">
<label for="currentPassword" class="col-md-4 col-lg-3 col-form-label">Current Password</label>
<label for="newPassword" class="col-md-4 col-lg-3 col-form-label">Katasandi
Baru</label>
<div class="col-md-8 col-lg-9">
<input name="password" type="password" class="form-control" id="currentPassword">
<input name="new_password" type="password" class="form-control"
id="newPassword">
</div>
</div>
<div class="row mb-3">
<label for="newPassword" class="col-md-4 col-lg-3 col-form-label">New Password</label>
<label for="renewPassword" class="col-md-4 col-lg-3 col-form-label">Konfirmasi
Katasandi Baru</label>
<div class="col-md-8 col-lg-9">
<input name="newpassword" type="password" class="form-control" id="newPassword">
<input name="new_password_confirmation" type="password" class="form-control"
id="renewPassword">
</div>
</div>
<div class="row mb-3">
<label for="renewPassword" class="col-md-4 col-lg-3 col-form-label">Re-enter New Password</label>
<div class="col-md-8 col-lg-9">
<input name="renewpassword" type="password" class="form-control" id="renewPassword">
</div>
</div>
<div class="text-center">
<button type="submit" class="btn btn-primary">Change Password</button>
<button type="submit" class="btn btn-primary">Simpan Perubahan</button>
</div>
@if (session('success'))
<div class="alert alert-success">
{{ session('success') }}
</div>
@endif
</form>
</div>
</form><!-- End Change Password Form -->
</div>
</div><!-- End Bordered Tabs -->
</div>
</div>
</div>
</div>
</section>
</main><!-- End #main -->
</main>
@endsection

View File

@ -1,5 +1,3 @@
<!DOCTYPE html>
<html lang="en">
@ -7,17 +5,20 @@
<meta charset="utf-8">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Pages / Register - NiceAdmin Bootstrap Template</title>
<title>Daftar Akun</title>
<link rel="icon" href="{{ asset('assets/pdam.png') }}">
<meta content="" name="description">
<meta content="" name="keywords">
<!-- Favicons -->
<link href="assets/img/favicon.png" rel="icon">
<link href="assets/img/apple-touch-icon.png" rel="apple-touch-icon">
<!-- Google Fonts -->
<link href="https://fonts.gstatic.com" rel="preconnect">
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,600,600i,700,700i|Nunito:300,300i,400,400i,600,600i,700,700i|Poppins:300,300i,400,400i,500,500i,600,600i,700,700i" rel="stylesheet">
<link
href="https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,600,600i,700,700i|Nunito:300,300i,400,400i,600,600i,700,700i|Poppins:300,300i,400,400i,500,500i,600,600i,700,700i"
rel="stylesheet">
<!-- Vendor CSS Files -->
<link href="assets/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">
@ -31,129 +32,83 @@
<!-- Template Main CSS File -->
<link href="assets/css/style.css" rel="stylesheet">
<!-- =======================================================
* Template Name: NiceAdmin
* Template URL: https://bootstrapmade.com/nice-admin-bootstrap-admin-html-template/
* Updated: Apr 20 2024 with Bootstrap v5.3.3
* Author: BootstrapMade.com
* License: https://bootstrapmade.com/license/
======================================================== -->
</head>
<body>
<main>
<div class="container">
<section class="section register min-vh-100 d-flex flex-column align-items-center justify-content-center py-4">
<section
class="section register min-vh-100 d-flex flex-column align-items-center justify-content-center py-4">
<div class="container">
<div class="row justify-content-center">
<div class="col-lg-4 col-md-6 d-flex flex-column align-items-center justify-content-center">
<div class="d-flex justify-content-center py-4">
<a href="index.html" class="logo d-flex align-items-center w-auto">
<img src="assets/img/logo.png" alt="">
<span class="d-none d-lg-block">NiceAdmin</span>
</a>
</div><!-- End Logo -->
<div class="card mb-3">
<div class="card-body">
<div class="pt-4 pb-2">
<h5 class="card-title text-center pb-0 fs-4">Create an Account</h5>
<p class="text-center small">Enter your personal details to create account</p>
<h5 class="card-title text-center pb-0 fs-4">Buat Akun</h5>
<p class="text-center small">Isi data pegawai</p>
</div>
<form class="row g-3 needs-validation" novalidate>
<form action="{{ route('register.store') }}" method="post"
class="row g-3 needs-validation" novalidate>
@csrf
<div class="col-12">
<label for="yourName" class="form-label">Your Name</label>
<input type="text" name="name" class="form-control" id="yourName" required>
<div class="invalid-feedback">Please, enter your name!</div>
</div>
<div class="col-12">
<label for="yourName" class="form-label">Kedudukan</label>
<div class="dropdown">
<a class="btn btn-outline-primary w-100 dropdown-toggle" href="#" role="button"
id="dropdownMenuLink" data-bs-toggle="dropdown" aria-expanded="false">
Pilih Kedudukan
</a>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuLink">
<li><a class="dropdown-item" href="#">Admin</a></li>
<li><a class="dropdown-item" href="#">Pegawai</a></li>
</ul>
</div>
</li>
</div>
<div class="col-12">
<label for="yourName" class="form-label">Kantor Unit</label>
<div class="dropdown">
<a class="btn btn-outline-primary w-100 dropdown-toggle" href="#" role="button"
id="dropdownMenuLink" data-bs-toggle="dropdown" aria-expanded="false">
Pilih Unit
</a>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuLink">
<li><a class="dropdown-item" href="#">Unit 1</a></li>
<li><a class="dropdown-item" href="#">Unit 2</a></li>
<li><a class="dropdown-item" href="#">Unit 3</a></li>
</ul>
</div>
</li>
</div>
<div class="col-12">
<label for="yourEmail" class="form-label">Your Email</label>
<input type="email" name="email" class="form-control" id="yourEmail" required>
<div class="invalid-feedback">Please enter a valid Email adddress!</div>
</div>
<div class="col-12">
<label for="yourUsername" class="form-label">Username</label>
<div class="input-group has-validation">
<span class="input-group-text" id="inputGroupPrepend">@</span>
<input type="text" name="username" class="form-control" id="yourUsername"
<label for="name" class="form-label">Nama Pegawai</label>
<input type="text" name="name" class="form-control" id="name"
required>
<div class="invalid-feedback">Please choose a username.</div>
<div class="invalid-feedback">Nama harus diisi!!</div>
</div>
</div>
<div class="col-12">
<label for="yourPassword" class="form-label">Password</label>
<input type="password" name="password" class="form-control" id="yourPassword"
<label for="role" class="form-label">Kedudukan</label>
<select name="role" class="form-select" id="role" required>
<option value="" disabled selected>Pilih Kedudukan</option>
<option value="admin">Admin</option>
<option value="user">User</option>
</select>
<div class="invalid-feedback">Kedudukan harus dipilih!!</div>
</div>
<div class="col-12">
<label for="unit_id" class="form-label">Kantor Unit</label>
<select name="unit_id" class="form-select" id="unit_id" required>
<option value="" disabled selected>Pilih Unit</option>
@foreach ($units as $unit)
<option value="{{ $unit->id }}">{{ $unit->name }}</option>
@endforeach
</select>
<div class="invalid-feedback">Unit harus dipilih!!</div>
</div>
<div class="col-12">
<label for="email" class="form-label">Email Pegawai</label>
<input type="email" name="email" class="form-control" id="email"
required>
<div class="invalid-feedback">Please enter your password!</div>
<div class="invalid-feedback">Email harus diisi!!</div>
</div>
<div class="col-12">
<button class="btn btn-primary w-100" type="submit">Create Account</button>
<label for="password" class="form-label">Katasandi</label>
<input type="password" name="password" class="form-control" id="password"
required>
<div class="invalid-feedback">Isi Katasandi!!</div>
</div>
<div class="col-12">
<button class="btn btn-primary w-100" type="submit">Buat Akun</button>
</div>
</form>
</div>
</div>
<div class="credits">
<!-- All the links in the footer should remain intact. -->
<!-- You can delete the links only if you purchased the pro version. -->
<!-- Licensing information: https://bootstrapmade.com/license/ -->
<!-- Purchase the pro version with working PHP/AJAX contact form: https://bootstrapmade.com/nice-admin-bootstrap-admin-html-template/ -->
Designed by <a href="https://bootstrapmade.com/">BootstrapMade</a>
Kembali ke <a href="{{ route('dashboard') }}">Halaman Utama</a>
</div>
</div>
</div>
</div>
</section>
</div>
</main><!-- End #main -->
</main>
<a href="#" class="back-to-top d-flex align-items-center justify-content-center"><i class="bi bi-arrow-up-short"></i></a>
<a href="#" class="back-to-top d-flex align-items-center justify-content-center"><i
class="bi bi-arrow-up-short"></i></a>
<!-- Vendor JS Files -->
<script src="assets/vendor/apexcharts/apexcharts.min.js"></script>

View File

@ -0,0 +1,106 @@
@extends('admin.layout.main')
@section('content')
<main id="main" class="main">
<div class="pagetitle">
<h1>Data Tables</h1>
</div>
<section class="section">
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-body">
<h5 class="card-title">Sensor Distance Data</h5>
<!-- Calendar for Date Range Selection -->
<div class="row mb-4">
<div class="col-md-4">
<label for="startDate">Start Date</label>
<input type="date" id="startDate" class="form-control" max="">
</div>
<div class="col-md-4">
<label for="endDate">End Date</label>
<input type="date" id="endDate" class="form-control" max="">
</div>
<div class="col-md-4 d-flex align-items-end">
<button class="btn btn-primary" id="filterBtn">Filter</button>
</div>
</div>
<!-- Table for displaying sensor data -->
<table class="table table-striped">
<thead>
<tr>
<th>Waktu</th>
<th>Distance Klampisan Atas</th>
<th>Distance Klampisan Bawah</th>
<th>Total Distance</th>
</tr>
</thead>
<tbody id="sensorDataTable">
<!-- Data will be populated here by JavaScript -->
</tbody>
</table>
</div>
</div>
</div>
</div>
</section>
</main>
@endsection
@section('scripts')
<script>
document.addEventListener('DOMContentLoaded', function() {
const startDateInput = document.getElementById("startDate");
const endDateInput = document.getElementById("endDate");
const sensorDataTable = document.getElementById("sensorDataTable");
const today = new Date().toISOString().split("T")[0];
startDateInput.max = today;
endDateInput.max = today;
startDateInput.addEventListener("change", function() {
const startDate = new Date(this.value);
const maxEndDate = new Date(startDate);
maxEndDate.setDate(startDate.getDate() + 7);
endDateInput.min = this.value;
endDateInput.max = maxEndDate.toISOString().split("T")[0];
});
endDateInput.addEventListener("change", function() {
startDateInput.max = this.value;
});
document.getElementById("filterBtn").addEventListener("click", function() {
const startDate = startDateInput.value;
const endDate = endDateInput.value;
if (startDate && endDate) {
fetch(`/getSensorData?start_date=${startDate}&end_date=${endDate}`)
.then(response => response.json())
.then(data => {
sensorDataTable.innerHTML = "";
data.forEach(row => {
const tableRow = `
<tr>
<td>${row.time_interval}</td>
<td>${row.distance_atas}</td>
<td>${row.distance_bawah}</td>
<td>${row.total_distance}</td>
</tr>
`;
sensorDataTable.innerHTML += tableRow;
});
})
.catch(error => console.error('Error fetching data:', error));
} else {
alert("Silakan pilih rentang tanggal.");
}
});
});
</script>
@endsection

View File

@ -0,0 +1,49 @@
@extends('admin.layout.main')
@section('content')
<main id="main" class="main">
<div class="pagetitle">
<h1>{{ ucwords($unit->name) }}</h1>
<nav>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{{ route('dashboard') }}">Beranda</a></li>
<li class="breadcrumb-item"><a href="{{ route('unit.index') }}">Unit</a></li>
<li class="breadcrumb-item active">Wilayah</li>
</ol>
</nav>
</div><!-- End Page Title -->
<section class="section">
@session('success')
<div class="alert alert-primary">{{ session()->get('success') }}</div>
@endsession
<div class="card">
<form method="post">
@csrf
<div class="card-header">Manajemen Wilayah</div>
<div class="card-body p-4">
<div class="row">
@foreach ($devices as $device)
<div class="col-lg-4 col-md-6 col-12">
<div class="d-flex align-items-center mb-2">
<input type="checkbox" name="device_names[]" value="{{ $device }}"
class="form-checkbox mr-3" @if (in_array($device, $unit?->device_names ?? [])) checked @endif
id="{{ $device }}" style="margin-right: 10px;">
<label for="{{ $device }}">
{{ $device }}
</label>
</div>
</div>
@endforeach
</div>
</div>
<div class="card-footer">
<button type="submit" class="btn btn-primary">Simpan</button>
</div>
</form>
</div>
</section>
</main>
@endsection

View File

@ -0,0 +1,142 @@
@extends('admin.layout.main')
@push('custom-resource')
<link href="https://cdn.syncfusion.com/ej2/material.css" rel="stylesheet">
<script src="https://cdn.syncfusion.com/ej2/dist/ej2.min.js"></script>
@endpush
@section('content')
<main id="main" class="main">
<div class="pagetitle">
<h1>Aliran PAM {{ ucwords($deviceName) }}</h1>
<nav>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{{ route('dashboard') }}">Beranda</a></li>
<li class="breadcrumb-item">{{ ucwords($deviceName) }}</li>
</ol>
</nav>
</div><!-- End Page Title -->
<section class="section">
<div class="row">
<!-- Chart Jarak di Kiri -->
@if (!empty($distanceData))
<div class="col-lg-6">
<div class="card flex-fill w-100">
<div class="card-body">
<h5 class="card-title">
Distance
</h5>
<p class="text-muted small">
Data terakhir:
@if ($latestDistanceDate)
{{ $latestDistanceDate->translatedFormat('d M Y, H:i') }}
@else
Belum ada data
@endif
</p>
<div class="d-flex justify-content-end align-items-center">
<a href="{{ route('admin.pages.dataprint', ['deviceName' => $deviceName]) }}"
class="btn btn-link p-0 mx-2" data-toggle="tooltip" data-placement="top"
title="Download Data {{ $deviceName }}">
<i class="bi bi-file-earmark-arrow-down" style="font-size: 24px; color: #007bff;"></i>
</a>
</div>
<div>
<div id="line-chart" style="height: 400px"></div>
</div>
</div>
</div>
</div>
@endif
<!-- Chart Gauge Tekanan di Kanan -->
@if ($pressureLatest !== null)
<div class="col-lg-6">
<div class="card flex-fill w-100">
<div class="card-body">
<h5 class="card-title">
Pressure
</h5>
<p class="text-muted small">
Data terakhir:
@if ($pressureLatestDate)
{{ $pressureLatestDate->translatedFormat('d M Y, H:i') }}
@else
Belum ada data
@endif
</p>
<div id="gauge-chart" style="height: 400px"></div>
</div>
</div>
</div>
@endif
</div>
</section>
</main>
@endsection
@section('js')
@if (!empty($distanceData))
<script>
var chart = new ej.charts.Chart({
primaryXAxis: {
majorGridLines: { width: 0 },
valueType: 'Category'
},
primaryYAxis: {
majorGridLines: { width: 1, color: '#ededed' },
minimum: 0,
},
chartArea: {
border: { width: 0 },
},
tooltip: {
enable: true,
shared: false,
format: '${point.x}: ${point.y}',
},
series: [{
dataSource: JSON.parse(@json($distanceData)),
xName: 'day',
yName: 'value',
type: 'Line',
width: 4,
marker: {
visible: true,
width: 10,
height: 10
},
}],
});
chart.appendTo('#line-chart');
</script>
@endif
@if ($pressureLatest !== null)
<script>
var circulargauge = new ej.circulargauge.CircularGauge({
axes: [{
minimum: 0,
maximum: 20,
startAngle: 225,
endAngle: 135,
ranges: [
{ start: 0, end: 10, color: '#3cb449' },
{ start: 10, end: 14, color: '#f2e715' },
{ start: 14, end: 20, color: '#e52128' }
],
majorTicks: { width: 0 },
minorTicks: { width: 0 },
pointers: [{ value: {{ $pressureLatest }} }]
}]
});
circulargauge.appendTo('#gauge-chart');
</script>
@endif
@endsection

View File

@ -1,191 +1,136 @@
@extends('admin.layout.main')
@push('custom-resource')
<link href="{{ asset('/') }}syncfusion/material.css" rel="stylesheet">
<script src="{{ asset('/') }}syncfusion/ej2.min.js" type="text/javascript"></script>
<script src="{{ asset('/') }}syncfusion/syncfusion-helper.js" type="text/javascript"></script>
@endpush
@section('content')
<main id="main" class="main">
<div class="pagetitle">
<h1>Bak ...</h1>
<h1>Bak {{ $deviceName }}</h1>
<nav>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{{ route('dashboard') }}">Halaman Utama</a></li>
<li class="breadcrumb-item">Bak ...</li>
<li class="breadcrumb-item">{{ $deviceName }}</li>
</ol>
</nav>
</div><!-- End Page Title -->
<p>Chart.JS Examples. You can check the <a href="https://www.chartjs.org/docs/latest/samples/"
target="_blank">official website</a> for more examples.</p>
<section class="section">
<div class="row">
<!-- Chart Jarak di Kiri -->
@if (!!$latest->distance)
<div class="col-lg-6">
<div class="card">
<div class="card flex-fill w-100">
<div class="card-body">
<h5 class="card-title">Line Chart</h5>
<!-- Line Chart -->
<canvas id="lineChart" style="max-height: 400px;"></canvas>
<script>
document.addEventListener("DOMContentLoaded", () => {
new Chart(document.querySelector('#lineChart'), {
type: 'line',
data: {
labels: ['1am', '2am', '3am', '4am', '5am', '6am', '7am', '8am',
'9am', '10am', '11am', '12am', '1pm', '2pm', '3pm',
'4pm', '5pm', '6pm', '8pm', '9pm', '10pm', '12pm'
],
datasets: [{
label: 'Line Chart',
data: [65, 59, 80, 81, 56, 55, 40],
fill: false,
borderColor: 'rgb(75, 192, 192)',
tension: 0.1
}]
},
options: {
scales: {
y: {
beginAtZero: true
}
}
}
});
});
</script>
<!-- End Line CHart -->
<h5 class="card-title">
Distance
</h5>
<a href="{{ url('/sensor-data/' . $deviceName) }}" class="float-right" data-toggle="tooltip" data-placement="top" title="Lihat Selengkapnya">
<i class="bi bi-box-arrow-up-right"></i>
</a>
<a href="{{ route('admin.pages.cobahabib', ['device_name' => $deviceName]) }}" class="float-right" data-toggle="tooltip" data-placement="top" title="Download File">
<i class="file-earmark-arrow-down"></i>
</a>
<div>
<div id="line-chart" style="height: 400px"></div>
</div>
</div>
</div>
<!-- Chart yang Anda buat -->
</div>
@endif
<!-- Chart Gauge Tekanan di Kanan -->
@if (!!$latest->pressure)
<div class="col-lg-6">
<div class="card">
<div class="card flex-fill w-100">
<div class="card-body">
<h5 class="card-title">Custom Doughnut Chart</h5>
<!-- Custom Doughnut Chart -->
<canvas id="myChart" style="max-height: 400px;"></canvas>
<script type="text/javascript"
src="https://cdn.jsdelivr.net/npm/chart.js/dist/chart.umd.min.js"></script>
<script>
// setup
const data = {
labels: ['score', 'gray area', 'another area'],
datasets: [{
label: 'Weekly Sales',
data: [100, 700],
borderColor: [
'rgba(255, 26, 104, 0.2)',
'rgba(0, 0, 0, 0.2)'
],
backgroundColor: [
'rgba(255, 26, 104, 0.2)',
'rgba(0, 0, 0, 0.2)'
],
borderWidth: 1,
cutout: '90%',
circumference: 180,
rotation: 270
}]
};
//teks
const gaugeChartText = {
id: 'gaugeChartText',
afterDatasetsDraw(chart, args, pluginOptions) {
const {
ctx,
data,
chartArea: {
top,
bottom,
left,
right,
width,
height
},
scales: {
r
}
} = chart;
ctx.save();
const xCoor = chart.getDatasetMeta(0).data[0].x;
const yCoor = chart.getDatasetMeta(0).data[0].y;
const score = data.datasets[0].data[0];
let rating;
if (score < 400) {
rating = 'sangat jauh';
}
if (score >= 401 && score <= 600) {
rating = 'sedang';
}
if (score >= 700 && score <= 750) {
rating = 'hampir penuh';
}
if (score >= 751) {
rating = 'penuh';
}
// ctx.fillRect(xCoor, yCoor, 400, 2);
function textLabel(text, x, y, fontSize, textBaseline, textAlign) {
ctx.font = `${fontSize}px sans-serif`;
ctx.fillStyle = '#666';
ctx.textBaseline = textBaseline;
ctx.textAlign = textAlign;
ctx.fillText(text, x, y);
}
textLabel('0cm', left, yCoor + 20, 20, 'top', 'left');
textLabel('800cm', right, yCoor + 20, 20, 'top', 'right');
textLabel(score, xCoor, yCoor - 50, 60, 'buttom', 'center');
textLabel(rating, xCoor, yCoor - 100, 30, 'top', 'center');
}
}
// config
const config = {
type: 'doughnut',
data,
options: {
aspectRatio: 1.5,
plugins: {
legend: {
display: false
},
tooltip: {
enabled: false
}
}
},
plugins: [gaugeChartText]
};
// render init block
const myChart = new Chart(
document.getElementById('myChart'),
config
);
// Instantly assign Chart.js version
const chartVersion = document.getElementById('chartVersion');
chartVersion.innerText = Chart.version;
</script>
<!-- End Custom Doughnut Chart -->
<h5 class="card-title">
Pressure
</h5>
<div id="gauge-chart" style="height: 400px"></div>
</div>
</div>
</div>
<!-- End Chart yang Anda buat -->
@endif
</div>
</section>
</main><!-- End #main -->
</main>
@endsection
@section('js')
@if (!!$latest->distance)
<script>
var chart = new ej.charts.Chart({
primaryXAxis: {
majorGridLines: {
width: 0
},
valueType: 'Category'
},
primaryYAxis: {
majorGridLines: {
width: 1,
color: '#ededed'
},
minimum: 0,
},
chartArea: {
border: {
width: 0,
},
},
series: [{
// dataSource for chart series
dataSource: JSON.parse('<?= $distanceLastWeek ?>'),
xName: 'day',
yName: 'value',
type: 'Line',
width: 4,
}],
});
chart.appendTo('#line-chart');
</script>
@endif
@if (!!$latest->pressure)
<script>
var circulargauge = new ej.circulargauge.CircularGauge({
axes: [{
minimum: 0,
maximum: 20,
startAngle: 270 - 45,
endAngle: 90 + 45,
ranges: [{
start: 0,
end: 10,
color: '#3cb449'
}, {
start: 10,
end: 14,
color: '#f2e715'
}, {
start: 14,
end: 20,
color: '#e52128'
}, ],
majorTicks: {
width: 0,
},
minorTicks: {
width: 0,
},
pointers: [{
value: '{{ $pressureLatest }}'
}]
}]
});
circulargauge.appendTo('#gauge-chart');
</script>
@endif
@endsection

View File

@ -0,0 +1,91 @@
@extends('admin.layout.main')
@push('custom-resource')
<link href="{{ asset('/') }}syncfusion/material.css" rel="stylesheet">
<script src="{{ asset('/') }}syncfusion/ej2.min.js" type="text/javascript"></script>
<script src="{{ asset('/') }}syncfusion/syncfusion-helper.js" type="text/javascript"></script>
@endpush
@section('content')
<main id="main" class="main">
<div class="pagetitle">
<h1>Data Unit</h1>
<nav>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{{ route('dashboard') }}">Beranda</a></li>
<li class="breadcrumb-item active" > Data Unit</li>
</ol>
</nav>
</div>
<section class="section">
@session('success')
<div class="alert alert-primary">{{ session()->get('success') }}</div>
@endsession
<div class="row">
<div class="col-md-4">
<div class="card">
<form action="" method="post">
@csrf
<div class="card-body p-3">
<div class="form-group">
<input type="text" placeholder="Nama Unit" class="form-control" name="name">
</div>
<div class="mt-3">
<button type="submit" class="btn btn-primary w-100">Tambah Unit</button>
</div>
</div>
</form>
</div>
</div>
</div>
<div class="card">
<div class="card-body p-3">
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th scope="col">No</th>
<th scope="col">Nama Unit</th>
<th scope="col">Devices</th>
<th scope="col">Opsi</th>
</tr>
</thead>
<tbody>
@foreach ($units as $key => $unit)
<tr>
<th scope="row">{{ $key + 1 }}</th>
<td>{{ $unit->name }}</td>
<td>
<a href="{{ route('unit.devices', $unit->id) }}" class="btn btn-sm btn-primary">
<i class="bi bi-eye"></i>
Selengkapnya
</a>
</td>
<td>
<form style="margin-left: 14px;" action="{{ route('unit.destroy', $unit->id) }}"
class="d-inline"
onsubmit="return confirm('anda yakin akan menghapus data unit ini?')"
method="post">
@method('DELETE')
@csrf
<button type="submit"
style="border: none; border-radius: 50rem; margin: 0;"
class="bg-white text-danger">
<i class="bi bi-trash"></i>
</button>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
</section>
</main>
@endsection

View File

@ -0,0 +1,52 @@
@extends('admin.layout.main')
@section('content')
<main id="main" class="main">
<div class="pagetitle">
<h1>{{ ucwords($user->name) }}</h1>
<nav>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{{ route('dashboard') }}">Halaman Utama</a></li>
<li class="breadcrumb-item"><a href="{{ route('users.index') }}">User</a></li>
<li class="breadcrumb-item">Device</li>
</ol>
</nav>
</div>
<section class="section">
@session('success')
<div class="alert alert-primary">{{ session()->get('success') }}</div>
@endsession
<div class="card">
<form method="post">
@csrf
<div class="card-header">Manajemen Device</div>
<div class="card-body p-4">
<div class="row">
@php
$userDevices = $user->getDevices();
@endphp
@foreach ($devices as $device)
<div class="col-lg-4 col-md-6 col-12">
<div class="d-flex align-items-center mb-2">
<input type="checkbox" name="devices[]" value="{{ $device }}"
class="form-checkbox mr-3" @if (in_array($device, $userDevices)) checked @endif
id="{{ $device }}" style="margin-right: 10px;">
<label for="{{ $device }}">
{{ $device }}
</label>
</div>
</div>
@endforeach
</div>
</div>
<div class="card-footer">
<button type="submit" class="btn btn-primary">Simpan</button>
</div>
</form>
</div>
</section>
</main>
@endsection

View File

@ -0,0 +1,26 @@
<?php
header('Content-Type: application/json; charset=utf8');
$koneksi = mysqli_connect("103.163.103.117:9306", "pdam", "pdamwng1", "pdam_web");
if ($_SERVER['REQUEST_METHOD'] === 'GET'){
$sql = "SELECT
DATE(created_at) AS tanggal,
MAX(distance) AS nilai_tertinggi,
MIN(distance) AS nilai_terendah
FROM
pdam_web.sensor_data
WHERE
device_name = 'Bakalan'
AND created_at >= CURDATE() - INTERVAL 7 DAY
GROUP BY
DATE(created_at)
ORDER BY
tanggal ASC;
";
$query = mysqli_query($koneksi, $sql);
$array_data = array();
while ($data = mysqli_fetch_assoc($query))
$array_data[] = $data;
}
echo json_encode($array_data);

View File

@ -0,0 +1,26 @@
<?php
header('Content-Type: application/json; charset=utf8');
$koneksi = mysqli_connect("103.163.103.117:9306", "pdam", "pdamwng1", "pdam_web");
if ($_SERVER['REQUEST_METHOD'] === 'GET'){
$sql = "SELECT
DATE(created_at) AS tanggal,
MAX(distance) AS nilai_tertinggi,
MIN(distance) AS nilai_terendah
FROM
pdam_web.sensor_data
WHERE
device_name = 'Bauresan'
AND created_at >= CURDATE() - INTERVAL 7 DAY
GROUP BY
DATE(created_at)
ORDER BY
tanggal ASC;
";
$query = mysqli_query($koneksi, $sql);
$array_data = array();
while ($data = mysqli_fetch_assoc($query))
$array_data[] = $data;
}
echo json_encode($array_data);

View File

@ -0,0 +1,26 @@
<?php
header('Content-Type: application/json; charset=utf8');
$koneksi = mysqli_connect("103.163.103.117:9306", "pdam", "pdamwng1", "pdam_web");
if ($_SERVER['REQUEST_METHOD'] === 'GET'){
$sql = "SELECT
DATE(created_at) AS tanggal,
MAX(distance) AS nilai_tertinggi,
MIN(distance) AS nilai_terendah
FROM
pdam_web.sensor_data
WHERE
device_name = 'Gandul'
AND created_at >= CURDATE() - INTERVAL 7 DAY
GROUP BY
DATE(created_at)
ORDER BY
tanggal ASC;
";
$query = mysqli_query($koneksi, $sql);
$array_data = array();
while ($data = mysqli_fetch_assoc($query))
$array_data[] = $data;
}
echo json_encode($array_data);

View File

@ -0,0 +1,26 @@
<?php
header('Content-Type: application/json; charset=utf8');
$koneksi = mysqli_connect("103.163.103.117:9306", "pdam", "pdamwng1", "pdam_web");
if ($_SERVER['REQUEST_METHOD'] === 'GET'){
$sql = "SELECT
DATE(created_at) AS tanggal,
MAX(distance) AS nilai_tertinggi,
MIN(distance) AS nilai_terendah
FROM
pdam_web.sensor_data
WHERE
device_name = 'Grobog'
AND created_at >= CURDATE() - INTERVAL 7 DAY
GROUP BY
DATE(created_at)
ORDER BY
tanggal ASC;
";
$query = mysqli_query($koneksi, $sql);
$array_data = array();
while ($data = mysqli_fetch_assoc($query))
$array_data[] = $data;
}
echo json_encode($array_data);

View File

@ -0,0 +1,26 @@
<?php
header('Content-Type: application/json; charset=utf8');
$koneksi = mysqli_connect("103.163.103.117:9306", "pdam", "pdamwng1", "pdam_web");
if ($_SERVER['REQUEST_METHOD'] === 'GET'){
$sql = "SELECT
DATE(created_at) AS tanggal,
MAX(distance) AS nilai_tertinggi,
MIN(distance) AS nilai_terendah
FROM
pdam_web.sensor_data
WHERE
device_name = 'Induk'
AND created_at >= CURDATE() - INTERVAL 7 DAY
GROUP BY
DATE(created_at)
ORDER BY
tanggal ASC;
";
$query = mysqli_query($koneksi, $sql);
$array_data = array();
while ($data = mysqli_fetch_assoc($query))
$array_data[] = $data;
}
echo json_encode($array_data);

View File

@ -0,0 +1,26 @@
<?php
header('Content-Type: application/json; charset=utf8');
$koneksi = mysqli_connect("103.163.103.117:9306", "pdam", "pdamwng1", "pdam_web");
if ($_SERVER['REQUEST_METHOD'] === 'GET'){
$sql = "SELECT
DATE(created_at) AS tanggal,
MAX(distance) AS nilai_tertinggi,
MIN(distance) AS nilai_terendah
FROM
pdam_web.sensor_data
WHERE
device_name = 'klampisan_atas'
AND created_at >= CURDATE() - INTERVAL 7 DAY
GROUP BY
DATE(created_at)
ORDER BY
tanggal ASC;
";
$query = mysqli_query($koneksi, $sql);
$array_data = array();
while ($data = mysqli_fetch_assoc($query))
$array_data[] = $data;
}
echo json_encode($array_data);

View File

@ -0,0 +1,26 @@
<?php
header('Content-Type: application/json; charset=utf8');
$koneksi = mysqli_connect("103.163.103.117:9306", "pdam", "pdamwng1", "pdam_web");
if ($_SERVER['REQUEST_METHOD'] === 'GET'){
$sql = "SELECT
DATE(created_at) AS tanggal,
MAX(distance) AS nilai_tertinggi,
MIN(distance) AS nilai_terendah
FROM
pdam_web.sensor_data
WHERE
device_name = 'klampisan_bawah'
AND created_at >= CURDATE() - INTERVAL 7 DAY
GROUP BY
DATE(created_at)
ORDER BY
tanggal ASC;
";
$query = mysqli_query($koneksi, $sql);
$array_data = array();
while ($data = mysqli_fetch_assoc($query))
$array_data[] = $data;
}
echo json_encode($array_data);

View File

@ -0,0 +1,70 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ganti Kata Sandi</title>
<link rel="icon" href="{{ asset('assets/logo.jpg') }}" type="image/x-icon">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
<link rel='stylesheet' href='//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css'>
<link rel="stylesheet" href="{{ asset('assets/style.css') }}">
</head>
<body>
<div class="login-box">
<div class="lb-header">
<a href="#" class="active" id="change-password-box-link">Ganti Kata Sandi Anda</a>
</div>
<form action="{{ route('change-password-proses') }}" class="email-login" method="post">
@csrf
<div class="u-form-group">
<input type="email" name="email" placeholder="Email" />
</div>
@error('email')
<small>{{ $message }}</small>
@enderror
<div class="u-form-group">
<input type="password" name="new_password" placeholder="Kata Sandi Baru" />
</div>
@error('new_password')
<small>{{ $message }}</small>
@enderror
<div class="u-form-group">
<input type="password" name="new_password_confirmation" placeholder="Konfirmasi Kata Sandi Baru" />
</div>
@error('new_password_confirmation')
<small>{{ $message }}</small>
@enderror
<div class="u-form-group">
<button>Ganti Kata Sandi</button>
</div>
<div class="u-form-group">
<a href="{{ route('login') }}" class="forgot-password">Masuk</a>
</div>
</form>
</div>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script src='//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<script src="{{ asset('assets/script.js') }}"></script>
@if($message = Session::get('failed'))
<script>
Swal.fire({
icon: "error",
title: "Gagal!",
text: "{{ $message }}",
});
</script>
@endif
@if($message = Session::get('success'))
<script>
Swal.fire({
position: "top-end",
icon: "success",
title: "{{ $message }}",
showConfirmButton: false,
timer: 1500 });
</script>
@endif
</body>
</html>

Some files were not shown because too many files have changed in this diff Show More