Initial commit for combined ProjectKP
This commit is contained in:
@@ -0,0 +1,206 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
class ActivityController extends Controller
|
||||
{
|
||||
private function apiUrl($endpoint = '')
|
||||
{
|
||||
return rtrim(env('BACKEND_API_URL'), '/') . '/' . ltrim($endpoint, '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* FUNGSI DASHBOARD ADMIN
|
||||
*/
|
||||
public function dashboard()
|
||||
{
|
||||
$response = Http::withToken(session('api_token'))
|
||||
->acceptJson()
|
||||
->get($this->apiUrl('/dashboard'));
|
||||
|
||||
$stats = ['total' => 0, 'selesai' => 0, 'proses' => 0, 'users' => 0];
|
||||
$activities = [];
|
||||
|
||||
if ($response->successful()) {
|
||||
$data = $response->json();
|
||||
if (isset($data['data']['stats'])) {
|
||||
$st = $data['data']['stats'];
|
||||
$stats['total'] = $st['total_tugas'] ?? 0;
|
||||
$stats['selesai'] = $st['status_selesai'] ?? 0;
|
||||
$stats['proses'] = $st['status_proses'] ?? 0;
|
||||
}
|
||||
if (isset($data['data']['recent_activities'])) {
|
||||
$activities = collect($data['data']['recent_activities'])->map(function($item) {
|
||||
$petugasNames = 'System';
|
||||
if (!empty($item['petugas']) && is_array($item['petugas'])) {
|
||||
$names = [];
|
||||
foreach ($item['petugas'] as $p) {
|
||||
if (isset($p['username'])) {
|
||||
$names[] = $p['username'];
|
||||
} elseif (isset($p['name'])) {
|
||||
$names[] = $p['name'];
|
||||
}
|
||||
}
|
||||
if (!empty($names)) {
|
||||
$petugasNames = implode(', ', $names);
|
||||
}
|
||||
}
|
||||
|
||||
return (object) [
|
||||
'id' => $item['id'],
|
||||
'nama_kegiatan' => $item['kegiatan'],
|
||||
'tanggal' => $item['tanggal_mulai'],
|
||||
'status' => $item['status'] == 'proses' ? 'on_progres' : $item['status'],
|
||||
'user' => (object) ['name' => $petugasNames],
|
||||
'keterangan' => $item['keterangan'] ?? $item['kegiatan'] ?? '-',
|
||||
];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$topUsers = [];
|
||||
$weeklyData = [0, 0, 0, 0, 0, 0, 0];
|
||||
$divisionProgress = [
|
||||
['name' => 'Operasional', 'pct' => 75, 'clr' => 'linear-gradient(90deg,#3b82f6,#6366f1)'],
|
||||
['name' => 'IT', 'pct' => 45, 'clr' => 'linear-gradient(90deg,#a855f7,#ec4899)'],
|
||||
['name' => 'SDM', 'pct' => 90, 'clr' => 'linear-gradient(90deg,#f97316,#f59e0b)'],
|
||||
['name' => 'Keuangan', 'pct' => 64, 'clr' => 'linear-gradient(90deg,#22c55e,#10b981)'],
|
||||
];
|
||||
|
||||
return view('admin.dashboard', compact(
|
||||
'stats',
|
||||
'activities',
|
||||
'topUsers',
|
||||
'weeklyData',
|
||||
'divisionProgress'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* HALAMAN INDEX (DAFTAR KEGIATAN DENGAN FILTER)
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$response = Http::withToken(session('api_token'))
|
||||
->acceptJson()
|
||||
->get($this->apiUrl('/penugasan'));
|
||||
|
||||
$items = collect([]);
|
||||
if ($response->successful()) {
|
||||
$data = $response->json();
|
||||
$items = collect($data['data'])->map(function($item) {
|
||||
$petugasNames = 'System';
|
||||
if (!empty($item['petugas']) && is_array($item['petugas'])) {
|
||||
$names = [];
|
||||
foreach ($item['petugas'] as $p) {
|
||||
if (isset($p['username'])) {
|
||||
$names[] = $p['username'];
|
||||
} elseif (isset($p['name'])) {
|
||||
$names[] = $p['name'];
|
||||
}
|
||||
}
|
||||
if (!empty($names)) {
|
||||
$petugasNames = implode(', ', $names);
|
||||
}
|
||||
}
|
||||
|
||||
return (object) [
|
||||
'id' => $item['id'],
|
||||
'nama_kegiatan' => $item['kegiatan'],
|
||||
'tanggal' => $item['tanggal_mulai'],
|
||||
'status' => $item['status'] == 'proses' ? 'on_progres' : $item['status'],
|
||||
'user' => (object) ['name' => $petugasNames],
|
||||
];
|
||||
});
|
||||
|
||||
// Sembunyikan kegiatan yang sudah dibatalkan
|
||||
$items = $items->filter(function($item) {
|
||||
return $item->status !== 'dibatalkan';
|
||||
})->values();
|
||||
}
|
||||
|
||||
// Simpan semua item sebelum filter untuk statistik
|
||||
$allItems = $items;
|
||||
|
||||
// FILTER SEARCH
|
||||
if ($request->search) {
|
||||
$search = strtolower($request->search);
|
||||
$items = $items->filter(function($item) use ($search) {
|
||||
return str_contains(strtolower($item->nama_kegiatan), $search) ||
|
||||
str_contains(strtolower($item->user->name), $search);
|
||||
});
|
||||
}
|
||||
|
||||
// FILTER STATUS
|
||||
if ($request->status && $request->status != 'semua') {
|
||||
$items = $items->filter(function($item) use ($request) {
|
||||
return $item->status === $request->status;
|
||||
});
|
||||
}
|
||||
|
||||
// Manual Pagination
|
||||
$perPage = 8;
|
||||
$currentPage = \Illuminate\Pagination\Paginator::resolveCurrentPage();
|
||||
$currentItems = $items->slice(($currentPage - 1) * $perPage, $perPage)->all();
|
||||
$activities = new \Illuminate\Pagination\LengthAwarePaginator($currentItems, count($items), $perPage, $currentPage, [
|
||||
'path' => \Illuminate\Pagination\Paginator::resolveCurrentPath(),
|
||||
'query' => $request->query(),
|
||||
]);
|
||||
|
||||
$divisis = collect(['-']);
|
||||
|
||||
return view('admin.kegiatan.index', compact('activities', 'divisis', 'allItems'));
|
||||
}
|
||||
|
||||
// DETAIL
|
||||
public function show($id)
|
||||
{
|
||||
$response = Http::withToken(session('api_token'))
|
||||
->acceptJson()
|
||||
->get($this->apiUrl('/penugasan/' . $id));
|
||||
|
||||
if (!$response->successful()) {
|
||||
return redirect()->route('admin.kegiatan.index')->with('error', 'Data tidak ditemukan');
|
||||
}
|
||||
|
||||
$data = $response->json()['data'];
|
||||
$petugas = collect($data['petugas'] ?? []);
|
||||
|
||||
$petugasNames = 'System';
|
||||
if ($petugas->isNotEmpty()) {
|
||||
$names = [];
|
||||
foreach ($petugas as $p) {
|
||||
if (isset($p['username'])) {
|
||||
$names[] = $p['username'];
|
||||
} elseif (isset($p['name'])) {
|
||||
$names[] = $p['name'];
|
||||
}
|
||||
}
|
||||
if (!empty($names)) {
|
||||
$petugasNames = implode(', ', $names);
|
||||
}
|
||||
}
|
||||
|
||||
$activity = (object) [
|
||||
'id' => $data['id'],
|
||||
'nomor_surat' => $data['nomor_surat'] ?? '-',
|
||||
'nama_kegiatan' => $data['kegiatan'],
|
||||
'tanggal' => $data['tanggal_mulai'],
|
||||
'tanggal_selesai' => $data['tanggal_selesai'] ?? null,
|
||||
'lokasi' => '-',
|
||||
'deskripsi' => '-',
|
||||
'updated_at' => $data['updated_at'] ?? now(),
|
||||
'status' => $data['status'] == 'proses' ? 'on_progres' : $data['status'],
|
||||
'user' => (object) ['name' => $petugasNames],
|
||||
'petugas' => $petugas,
|
||||
];
|
||||
|
||||
return view('admin.kegiatan.detail', compact('activity'));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,555 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Carbon\Carbon;
|
||||
use Carbon\CarbonPeriod;
|
||||
|
||||
class SuperAdminController extends Controller
|
||||
{
|
||||
private function apiUrl($endpoint = '')
|
||||
{
|
||||
return rtrim(env('BACKEND_API_URL'), '/') . '/' . ltrim($endpoint, '/');
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$response = \Illuminate\Support\Facades\Http::withToken(session('api_token'))
|
||||
->get($this->apiUrl('/penugasan'), ['is_archived' => 'false']);
|
||||
|
||||
$dashResponse = \Illuminate\Support\Facades\Http::withToken(session('api_token'))
|
||||
->get($this->apiUrl('/dashboard'));
|
||||
|
||||
$items = collect([]);
|
||||
if ($response->successful()) {
|
||||
$items = collect($response->json()['data'])->map(function($item) {
|
||||
return (object) [
|
||||
'id' => $item['id'],
|
||||
'nama_kegiatan' => $item['kegiatan'],
|
||||
'tanggal' => $item['tanggal_mulai'],
|
||||
'tanggal_selesai' => $item['tanggal_selesai'] ?? null,
|
||||
'created_at' => \Carbon\Carbon::parse($item['created_at']),
|
||||
'status' => $item['status'] == 'proses' ? 'on_progres' : $item['status'],
|
||||
'user' => (object) ['name' => $item['pembuat']['name'] ?? 'System'],
|
||||
'petugas' => $item['petugas'] ?? [],
|
||||
'pembuat' => $item['pembuat'] ?? []
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
$allItems = clone $items;
|
||||
$items = $items->filter(function($item) {
|
||||
return $item->status !== 'dibatalkan';
|
||||
})->values();
|
||||
|
||||
// Manual Pagination
|
||||
$perPage = 10;
|
||||
$currentPage = \Illuminate\Pagination\Paginator::resolveCurrentPage();
|
||||
$currentItems = $items->slice(($currentPage - 1) * $perPage, $perPage)->all();
|
||||
$activities = new \Illuminate\Pagination\LengthAwarePaginator($currentItems, count($items), $perPage, $currentPage, [
|
||||
'path' => \Illuminate\Pagination\Paginator::resolveCurrentPath()
|
||||
]);
|
||||
|
||||
$stats = [
|
||||
'total' => $items->count(),
|
||||
'users' => 0, // diisi nanti
|
||||
'proses' => $items->where('status', 'on_progres')->count(),
|
||||
'deleted' => $allItems->where('status', 'dibatalkan')->count(),
|
||||
];
|
||||
|
||||
// Ambil User
|
||||
$usersResponse = \Illuminate\Support\Facades\Http::withToken(session('api_token'))
|
||||
->get($this->apiUrl('/users'));
|
||||
$users = collect([]);
|
||||
if ($usersResponse->successful()) {
|
||||
$users = collect($usersResponse->json()['data']);
|
||||
$stats['users'] = $users->count();
|
||||
}
|
||||
|
||||
// ── Top 5 Petugas (Dihitung dari penugasan)
|
||||
$topUsers = $users->map(function($u) use ($items) {
|
||||
$count = $items->filter(function($item) use ($u) {
|
||||
if (isset($item->petugas) && is_array($item->petugas)) {
|
||||
foreach ($item->petugas as $p) {
|
||||
if (isset($p['id']) && $p['id'] == $u['id']) return true;
|
||||
}
|
||||
}
|
||||
return isset($item->pembuat['id']) && $item->pembuat['id'] == $u['id'];
|
||||
})->count();
|
||||
|
||||
return (object) [
|
||||
'name' => $u['name'] ?? 'System',
|
||||
'activities_count' => $count
|
||||
];
|
||||
})->sortByDesc('activities_count')->take(5)->values();
|
||||
|
||||
// ── Data Grafik
|
||||
$chartData = $this->buildChartData($items);
|
||||
|
||||
$system = [
|
||||
'server' => rand(25, 55),
|
||||
'database' => rand(45, 75),
|
||||
'storage' => rand(60, 85),
|
||||
];
|
||||
|
||||
return view('superadmin.dashboard', compact(
|
||||
'activities',
|
||||
'stats',
|
||||
'topUsers',
|
||||
'chartData',
|
||||
'system'
|
||||
));
|
||||
}
|
||||
|
||||
private function buildChartData($items)
|
||||
{
|
||||
$now = Carbon::now();
|
||||
|
||||
// ── MINGGU INI ─────────────────────────────────
|
||||
$startOfWeek = $now->copy()->startOfWeek(Carbon::MONDAY);
|
||||
$endOfWeek = $now->copy()->endOfWeek(Carbon::SUNDAY);
|
||||
|
||||
$weekLabels = ['Sen', 'Sel', 'Rab', 'Kam', 'Jum', 'Sab', 'Min'];
|
||||
$weekValues = array_fill(0, 7, 0);
|
||||
|
||||
foreach ($items as $item) {
|
||||
$date = $item->created_at;
|
||||
if ($date->between($startOfWeek, $endOfWeek)) {
|
||||
$idx = $date->dayOfWeekIso - 1;
|
||||
$weekValues[$idx]++;
|
||||
}
|
||||
}
|
||||
|
||||
// ── BULAN INI ──────────────────────────────
|
||||
$startOfMonth = $now->copy()->startOfMonth();
|
||||
$endOfMonth = $now->copy()->endOfMonth();
|
||||
$daysInMonth = $now->daysInMonth;
|
||||
|
||||
$monthLabels = [];
|
||||
$monthValues = array_fill(0, $daysInMonth, 0);
|
||||
|
||||
for ($i = 1; $i <= $daysInMonth; $i++) {
|
||||
$monthLabels[] = ($i % 5 === 1 || $i === 1) ? (string) $i : '';
|
||||
}
|
||||
|
||||
foreach ($items as $item) {
|
||||
$date = $item->created_at;
|
||||
if ($date->between($startOfMonth, $endOfMonth)) {
|
||||
$monthValues[$date->day - 1]++;
|
||||
}
|
||||
}
|
||||
|
||||
// ── TAHUN INI ────────────────────────────────
|
||||
$monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'Mei', 'Jun', 'Jul', 'Ags', 'Sep', 'Okt', 'Nov', 'Des'];
|
||||
$yearValues = array_fill(0, 12, 0);
|
||||
|
||||
foreach ($items as $item) {
|
||||
$date = $item->created_at;
|
||||
if ($date->year === $now->year) {
|
||||
$yearValues[$date->month - 1]++;
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'week' => [
|
||||
'labels' => $weekLabels,
|
||||
'values' => $weekValues,
|
||||
'todayIndex' => $now->dayOfWeekIso - 1,
|
||||
],
|
||||
'month' => [
|
||||
'labels' => $monthLabels,
|
||||
'values' => $monthValues,
|
||||
'todayIndex' => $now->day - 1,
|
||||
],
|
||||
'year' => [
|
||||
'labels' => $monthNames,
|
||||
'values' => $yearValues,
|
||||
'todayIndex' => $now->month - 1,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function show($id)
|
||||
{
|
||||
$response = \Illuminate\Support\Facades\Http::withToken(session('api_token'))
|
||||
->get($this->apiUrl('/penugasan/' . $id));
|
||||
|
||||
if (!$response->successful()) {
|
||||
return redirect()->back()->with('error', 'Kegiatan tidak ditemukan.');
|
||||
}
|
||||
$data = $response->json()['data'];
|
||||
$activity = (object) [
|
||||
'id' => $data['id'],
|
||||
'nama_kegiatan' => $data['kegiatan'],
|
||||
'tanggal' => $data['tanggal_mulai'],
|
||||
'tanggal_selesai' => $data['tanggal_selesai'] ?? null,
|
||||
'status' => $data['status'] == 'proses' ? 'on_progres' : $data['status'],
|
||||
'deskripsi' => $data['keterangan'] ?? '-',
|
||||
'lokasi' => $data['lokasi'] ?? '-',
|
||||
'status_note' => $data['status_note'] ?? null,
|
||||
'updated_at' => \Carbon\Carbon::parse($data['updated_at'] ?? now()),
|
||||
'user' => (object) ['name' => $data['pembuat']['name'] ?? 'System'],
|
||||
'petugas' => $data['petugas'] ?? [],
|
||||
'nomor_surat' => $data['nomor_surat'] ?? '-',
|
||||
'progress' => $data['progress'] ?? []
|
||||
];
|
||||
|
||||
return view('superadmin.kegiatan.show', compact('activity'));
|
||||
}
|
||||
|
||||
public function approve(Request $request, $id)
|
||||
{
|
||||
$response = \Illuminate\Support\Facades\Http::withToken(session('api_token'))
|
||||
->post($this->apiUrl("/penugasan/{$id}/update-status"), [
|
||||
'status' => 'telah_ditinjau'
|
||||
]);
|
||||
|
||||
if ($response->successful()) {
|
||||
return redirect()->back()->with('success', 'Kegiatan berhasil disetujui (Telah Ditinjau).');
|
||||
}
|
||||
|
||||
return redirect()->back()->with('error', 'Terjadi kesalahan saat menyetujui kegiatan.');
|
||||
}
|
||||
|
||||
public function revision(Request $request, $id)
|
||||
{
|
||||
$request->validate([
|
||||
'status_note' => 'required|string|min:5|max:255'
|
||||
]);
|
||||
|
||||
$response = \Illuminate\Support\Facades\Http::withToken(session('api_token'))
|
||||
->post($this->apiUrl("/penugasan/{$id}/update-status"), [
|
||||
'status' => 'proses',
|
||||
'status_note' => 'REVISI dari ' . session('user_name') . ': ' . $request->status_note
|
||||
]);
|
||||
|
||||
if ($response->successful()) {
|
||||
return redirect()->back()->with('success', 'Kegiatan dikembalikan ke pegawai untuk direvisi.');
|
||||
}
|
||||
|
||||
return redirect()->back()->with('error', 'Terjadi kesalahan saat meminta revisi.');
|
||||
}
|
||||
|
||||
public function destroy(Request $request, $id)
|
||||
{
|
||||
$request->validate([
|
||||
'alasan_hapus' => 'required|string|min:10|max:500',
|
||||
]);
|
||||
|
||||
$response = \Illuminate\Support\Facades\Http::withToken(session('api_token'))
|
||||
->post($this->apiUrl("/penugasan/{$id}/delete"), [
|
||||
'alasan' => $request->alasan_hapus
|
||||
]);
|
||||
|
||||
if ($response->successful()) {
|
||||
return redirect()->back()->with('success', 'Kegiatan berhasil dibatalkan dan dicatat dalam log.');
|
||||
}
|
||||
|
||||
return redirect()->back()->with('error', 'Gagal membatalkan kegiatan.');
|
||||
}
|
||||
|
||||
public function arsip()
|
||||
{
|
||||
$response = \Illuminate\Support\Facades\Http::withToken(session('api_token'))
|
||||
->get($this->apiUrl('/penugasan'), ['is_archived' => 'true']);
|
||||
|
||||
$items = collect([]);
|
||||
if ($response->successful()) {
|
||||
$items = collect($response->json()['data'])->map(function($item) {
|
||||
return (object) [
|
||||
'id' => $item['id'],
|
||||
'nama_kegiatan' => $item['kegiatan'],
|
||||
'tanggal' => $item['tanggal_mulai'],
|
||||
'tanggal_selesai' => $item['tanggal_selesai'] ?? null,
|
||||
'created_at' => \Carbon\Carbon::parse($item['created_at']),
|
||||
'status' => $item['status'] == 'proses' ? 'on_progres' : $item['status'],
|
||||
'user' => (object) ['name' => $item['pembuat']['name'] ?? 'System'],
|
||||
'petugas' => $item['petugas'] ?? [],
|
||||
'pembuat' => $item['pembuat'] ?? []
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
// Manual Pagination
|
||||
$perPage = 10;
|
||||
$currentPage = \Illuminate\Pagination\Paginator::resolveCurrentPage();
|
||||
$currentItems = $items->slice(($currentPage - 1) * $perPage, $perPage)->all();
|
||||
$activities = new \Illuminate\Pagination\LengthAwarePaginator($currentItems, count($items), $perPage, $currentPage, [
|
||||
'path' => \Illuminate\Pagination\Paginator::resolveCurrentPath()
|
||||
]);
|
||||
|
||||
return view('superadmin.arsip.index', compact('activities'));
|
||||
}
|
||||
|
||||
public function archive($id)
|
||||
{
|
||||
$response = \Illuminate\Support\Facades\Http::withToken(session('api_token'))
|
||||
->post($this->apiUrl("/penugasan/{$id}/archive"));
|
||||
|
||||
if ($response->successful()) {
|
||||
return redirect()->back()->with('success', 'Status arsip laporan berhasil diperbarui.');
|
||||
}
|
||||
|
||||
return redirect()->back()->with('error', 'Gagal memperbarui status arsip laporan.');
|
||||
}
|
||||
|
||||
public function userIndex()
|
||||
{
|
||||
// Panggil API Penugasan untuk menghitung activities dinamis
|
||||
$penugasanResponse = \Illuminate\Support\Facades\Http::withToken(session('api_token'))
|
||||
->get($this->apiUrl('/penugasan'));
|
||||
$items = collect([]);
|
||||
if ($penugasanResponse->successful()) {
|
||||
$items = collect($penugasanResponse->json()['data']);
|
||||
}
|
||||
|
||||
// Panggil API Users
|
||||
$response = \Illuminate\Support\Facades\Http::withToken(session('api_token'))
|
||||
->get($this->apiUrl('/users'));
|
||||
|
||||
$users = collect([]);
|
||||
if ($response->successful()) {
|
||||
$users = collect($response->json()['data'])->map(function($u) use ($items) {
|
||||
$activitiesCount = $items->filter(function($item) use ($u) {
|
||||
// Cek apakah user ada di array petugas
|
||||
if (isset($item['petugas']) && is_array($item['petugas'])) {
|
||||
foreach ($item['petugas'] as $p) {
|
||||
if ($p['id'] == $u['id']) return true;
|
||||
}
|
||||
}
|
||||
// Fallback cek pembuat
|
||||
return ($item['pembuat']['id'] ?? null) == $u['id'];
|
||||
})->count();
|
||||
|
||||
return (object) [
|
||||
'id' => $u['id'],
|
||||
'name' => $u['name'],
|
||||
'username' => $u['username'],
|
||||
'role' => $u['role'],
|
||||
'created_at' => isset($u['created_at']) ? \Carbon\Carbon::parse($u['created_at']) : now(),
|
||||
'activities_count' => $activitiesCount
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
// Manual Pagination
|
||||
$perPage = 15;
|
||||
$currentPage = \Illuminate\Pagination\Paginator::resolveCurrentPage();
|
||||
$currentItems = $users->slice(($currentPage - 1) * $perPage, $perPage)->all();
|
||||
$paginatedUsers = new \Illuminate\Pagination\LengthAwarePaginator($currentItems, $users->count(), $perPage, $currentPage, [
|
||||
'path' => \Illuminate\Pagination\Paginator::resolveCurrentPath()
|
||||
]);
|
||||
|
||||
$stats = [
|
||||
'total' => $users->count(),
|
||||
'active' => $users->where('activities_count', '>', 0)->count(),
|
||||
'activities' => $users->sum('activities_count'),
|
||||
'max_activities' => max($users->max('activities_count') ?? 1, 1),
|
||||
];
|
||||
|
||||
return view('superadmin.user.index', ['users' => $paginatedUsers, 'stats' => $stats]);
|
||||
}
|
||||
|
||||
public function createUser()
|
||||
{
|
||||
return view('superadmin.user.create-user');
|
||||
}
|
||||
|
||||
public function storeUser(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'name' => 'required|string',
|
||||
'username' => 'required|string',
|
||||
'password' => 'required|string|min:6',
|
||||
'role' => 'required|in:user,admin,superadmin',
|
||||
]);
|
||||
|
||||
$response = \Illuminate\Support\Facades\Http::withToken(session('api_token'))
|
||||
->acceptJson()
|
||||
->post($this->apiUrl('/register'), [
|
||||
'name' => $request->name,
|
||||
'username' => $request->username,
|
||||
'password' => $request->password,
|
||||
'role' => $request->role,
|
||||
]);
|
||||
|
||||
if ($response->successful()) {
|
||||
return redirect()->route('admin.superadmin.user.index')->with('success', 'Pengguna berhasil ditambahkan');
|
||||
}
|
||||
|
||||
if ($response->status() === 422) {
|
||||
return back()->withErrors($response->json('errors'))->withInput();
|
||||
}
|
||||
|
||||
return back()->with('error', $response->json('message') ?? 'Gagal menambah pengguna')->withInput();
|
||||
}
|
||||
|
||||
public function editUser($id)
|
||||
{
|
||||
$response = \Illuminate\Support\Facades\Http::withToken(session('api_token'))
|
||||
->get($this->apiUrl("/users/{$id}"));
|
||||
|
||||
if ($response->successful()) {
|
||||
$userData = $response->json()['data'];
|
||||
$user = (object) [
|
||||
'id' => $userData['id'],
|
||||
'name' => $userData['name'],
|
||||
'username' => $userData['username'],
|
||||
'role' => $userData['role'],
|
||||
'email' => $userData['email'] ?? '',
|
||||
'created_at' => isset($userData['created_at'])
|
||||
? \Carbon\Carbon::parse($userData['created_at'])
|
||||
: now(),
|
||||
];
|
||||
return view('superadmin.user.edit-user', compact('user'));
|
||||
}
|
||||
return redirect()->back()->with('error', 'User tidak ditemukan atau gagal mengambil data.');
|
||||
}
|
||||
|
||||
public function updateUser(Request $request, $id)
|
||||
{
|
||||
$request->validate([
|
||||
'name' => 'required',
|
||||
'username' => 'required',
|
||||
'role' => 'required',
|
||||
'password' => 'nullable|min:6|confirmed',
|
||||
]);
|
||||
|
||||
$payload = $request->only('name', 'username', 'role');
|
||||
if ($request->filled('password')) {
|
||||
$payload['password'] = $request->password;
|
||||
}
|
||||
|
||||
$response = \Illuminate\Support\Facades\Http::withToken(session('api_token'))
|
||||
->acceptJson()
|
||||
->put($this->apiUrl("/users/{$id}"), $payload);
|
||||
|
||||
if ($response->successful()) {
|
||||
return redirect()->route('admin.superadmin.user.index')->with('success', 'User berhasil diupdate');
|
||||
}
|
||||
|
||||
if ($response->status() === 422) {
|
||||
return back()->withErrors($response->json('errors'))->withInput();
|
||||
}
|
||||
|
||||
return redirect()->back()->with('error', 'Gagal update user.')->withInput();
|
||||
}
|
||||
|
||||
// 🔥 DELETE USER
|
||||
public function destroyUser($id)
|
||||
{
|
||||
$response = \Illuminate\Support\Facades\Http::withToken(session('api_token'))
|
||||
->delete($this->apiUrl('/users/' . $id));
|
||||
|
||||
if ($response->successful()) {
|
||||
return redirect()->route('admin.superadmin.user.index')->with('success', 'Pengguna berhasil dihapus');
|
||||
}
|
||||
|
||||
return back()->with('error', 'Gagal menghapus pengguna');
|
||||
}
|
||||
|
||||
// 🔥 CREATE KEGIATAN
|
||||
public function createKegiatan()
|
||||
{
|
||||
// Ambil data users untuk dropdown pilihan pegawai (opsional)
|
||||
$usersResponse = \Illuminate\Support\Facades\Http::withToken(session('api_token'))
|
||||
->get($this->apiUrl('/users'));
|
||||
|
||||
$users = [];
|
||||
if ($usersResponse->successful()) {
|
||||
$allUsers = $usersResponse->json()['data'] ?? [];
|
||||
// Hanya tampilkan user dengan role "user" (Pegawai/Petugas)
|
||||
$users = array_filter($allUsers, function($u) {
|
||||
return isset($u['role']) && strtolower($u['role']) === 'user';
|
||||
});
|
||||
}
|
||||
|
||||
return view('superadmin.kegiatan.create', compact('users'));
|
||||
}
|
||||
|
||||
// 🔥 STORE KEGIATAN
|
||||
public function storeKegiatan(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'nomor_surat' => 'required|string',
|
||||
'kegiatan' => 'required|string',
|
||||
'tanggal_mulai' => 'required|date',
|
||||
'tanggal_selesai' => 'nullable|date',
|
||||
'pegawai_ids' => 'required|array',
|
||||
]);
|
||||
|
||||
$payload = [
|
||||
'nomor_surat' => $request->nomor_surat,
|
||||
'kegiatan' => $request->kegiatan,
|
||||
'tanggal_mulai' => $request->tanggal_mulai,
|
||||
'tanggal_selesai' => $request->tanggal_selesai,
|
||||
'pegawai_ids' => $request->pegawai_ids,
|
||||
];
|
||||
|
||||
$response = \Illuminate\Support\Facades\Http::withToken(session('api_token'))
|
||||
->acceptJson()
|
||||
->post($this->apiUrl('/penugasan'), $payload);
|
||||
|
||||
if ($response->successful()) {
|
||||
return redirect()->route('admin.superadmin.dashboard')->with('success', 'Tugas baru berhasil dibuat');
|
||||
}
|
||||
|
||||
if ($response->status() === 422) {
|
||||
return back()->withErrors($response->json('errors'))->withInput();
|
||||
}
|
||||
|
||||
return back()->with('error', 'Gagal membuat tugas baru: ' . $response->json('message', 'Error API'))->withInput();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function export(Request $request)
|
||||
{
|
||||
$columns = $request->input('columns', []);
|
||||
|
||||
$response = \Illuminate\Support\Facades\Http::withToken(session('api_token'))
|
||||
->get($this->apiUrl('/export-penugasan'), [
|
||||
'columns' => $columns
|
||||
]);
|
||||
|
||||
if ($response->successful()) {
|
||||
$fileName = 'Laporan_Penugasan.xlsx';
|
||||
$contentDisposition = $response->header('Content-Disposition');
|
||||
|
||||
if ($contentDisposition && preg_match('/filename="?([^"]+)"?/', $contentDisposition, $matches)) {
|
||||
$fileName = $matches[1];
|
||||
}
|
||||
|
||||
return response($response->body())
|
||||
->header('Content-Type', $response->header('Content-Type') ?? 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
|
||||
->header('Content-Disposition', 'attachment; filename="' . $fileName . '"');
|
||||
}
|
||||
|
||||
return back()->with('error', 'Gagal mengunduh laporan: Endpoint backend mungkin bermasalah atau tidak tersedia.');
|
||||
}
|
||||
|
||||
public function chartData(Request $request)
|
||||
{
|
||||
$mode = $request->get('mode', 'week');
|
||||
$response = \Illuminate\Support\Facades\Http::withToken(session('api_token'))
|
||||
->get($this->apiUrl('/penugasan'));
|
||||
|
||||
$items = collect([]);
|
||||
if ($response->successful()) {
|
||||
$items = collect($response->json()['data'])->filter(function($item) {
|
||||
return $item['status'] !== 'dibatalkan';
|
||||
})->map(function($item) {
|
||||
return (object) ['created_at' => \Carbon\Carbon::parse($item['created_at'])];
|
||||
});
|
||||
}
|
||||
$data = $this->buildChartData($items);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => $data[$mode] ?? $data['week'],
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user