29 Mei 2026

This commit is contained in:
[Valentino Heman Budiarto] 2026-05-29 18:55:54 +07:00
parent d2c6fb0d69
commit 5e005e8524
12 changed files with 29 additions and 23 deletions

3
.gitignore vendored
View File

@ -7,4 +7,5 @@ backend/*.exe
backend/s-class-backend backend/s-class-backend
# Mengabaikan file environment (kalau nanti ada) # Mengabaikan file environment (kalau nanti ada)
.env .env
.env.local

View File

@ -79,7 +79,7 @@ func main() {
func CORSMiddleware() gin.HandlerFunc { func CORSMiddleware() gin.HandlerFunc {
return func(c *gin.Context) { return func(c *gin.Context) {
c.Writer.Header().Set("Access-Control-Allow-Origin", "http://localhost:3000") c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true") c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With") c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, PATCH") c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, PATCH")

View File

@ -13,7 +13,7 @@ export default function ApprovalsPage() {
try { try {
const token = localStorage.getItem("token"); const token = localStorage.getItem("token");
// Mengambil dari fungsi GetAllBookings di backend // Mengambil dari fungsi GetAllBookings di backend
const res = await axios.get("http://localhost:8080/api/bookings", { const res = await axios.get("http://172.17.110.6:8080/api/bookings", {
headers: { Authorization: `Bearer ${token}` } headers: { Authorization: `Bearer ${token}` }
}); });
setBookings(res.data.data); setBookings(res.data.data);
@ -32,7 +32,7 @@ export default function ApprovalsPage() {
const token = localStorage.getItem("token"); const token = localStorage.getItem("token");
// Mengirim UUID booking_id ke backend Golang // Mengirim UUID booking_id ke backend Golang
await axios.put( await axios.put(
`http://localhost:8080/api/bookings/${bookingId}/status`, `http://172.17.110.6:8080/api/bookings/${bookingId}/status`,
{ status: newStatus }, { status: newStatus },
{ headers: { Authorization: `Bearer ${token}` } } { headers: { Authorization: `Bearer ${token}` } }
); );

View File

@ -8,7 +8,7 @@ export default function PowerMonitoringPage() {
const fetchPowerStatus = async () => { const fetchPowerStatus = async () => {
try { try {
const response = await fetch("http://localhost:8080/api/hardware/power-status"); const response = await fetch("http://172.17.110.6:8080/api/hardware/power-status");
const data = await response.json(); const data = await response.json();
// Asumsikan data dari HA berupa string angka, kita update ke room D101 // Asumsikan data dari HA berupa string angka, kita update ke room D101
@ -74,7 +74,7 @@ useEffect(() => {
try { try {
// Tembak API Golang (Ganti dengan endpoint aslimu jika berbeda) // Tembak API Golang (Ganti dengan endpoint aslimu jika berbeda)
const response = await fetch("http://localhost:8080/api/hardware/control", { const response = await fetch("http://172.17.110.6:8080/api/hardware/control", {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
body: JSON.stringify({ device: backendDevice, action: actionType }), body: JSON.stringify({ device: backendDevice, action: actionType }),

View File

@ -21,7 +21,7 @@ export default function AdminDashboard() {
const token = localStorage.getItem("token"); const token = localStorage.getItem("token");
// 1. Ambil SEMUA booking pakai endpoint yang sudah ada, lalu filter di Frontend // 1. Ambil SEMUA booking pakai endpoint yang sudah ada, lalu filter di Frontend
const bookRes = await axios.get("http://localhost:8080/api/bookings", { const bookRes = await axios.get("http://172.17.110.6:8080/api/bookings", {
headers: { Authorization: `Bearer ${token}` } headers: { Authorization: `Bearer ${token}` }
}); });
@ -31,7 +31,7 @@ export default function AdminDashboard() {
setPendingBookings(pendingOnly); setPendingBookings(pendingOnly);
// 2. Ambil daftar ruangan biasa, lalu kita sisipkan "Dummy Power" untuk UI // 2. Ambil daftar ruangan biasa, lalu kita sisipkan "Dummy Power" untuk UI
const roomRes = await axios.get("http://localhost:8080/api/rooms", { const roomRes = await axios.get("http://172.17.110.6:8080/api/rooms", {
headers: { Authorization: `Bearer ${token}` } headers: { Authorization: `Bearer ${token}` }
}); });
@ -54,7 +54,7 @@ export default function AdminDashboard() {
try { try {
const token = localStorage.getItem("token"); const token = localStorage.getItem("token");
// Mengirim status 'Approved' atau 'Rejected' ke backend // Mengirim status 'Approved' atau 'Rejected' ke backend
await axios.put(`http://localhost:8080/api/bookings/${id}/status`, await axios.put(`http://172.17.110.6:8080/api/bookings/${id}/status`,
{ status: status }, { status: status },
{ headers: { Authorization: `Bearer ${token}` } } { headers: { Authorization: `Bearer ${token}` } }
); );

View File

@ -11,7 +11,7 @@ export default function ManageRoomsPage() {
const fetchRooms = async () => { const fetchRooms = async () => {
try { try {
const token = localStorage.getItem("token"); const token = localStorage.getItem("token");
const res = await axios.get("http://localhost:8080/api/rooms", { const res = await axios.get("http://172.17.110.6:8080/api/rooms", {
headers: { Authorization: `Bearer ${token}` } headers: { Authorization: `Bearer ${token}` }
}); });
setRooms(res.data.data); setRooms(res.data.data);
@ -33,7 +33,7 @@ export default function ManageRoomsPage() {
try { try {
const token = localStorage.getItem("token"); const token = localStorage.getItem("token");
await axios.put(`http://localhost:8080/api/admin/rooms/${roomId}/status`, await axios.put(`http://172.17.110.6:8080/api/admin/rooms/${roomId}/status`,
{ status: newStatus }, { status: newStatus },
{ headers: { Authorization: `Bearer ${token}` } } { headers: { Authorization: `Bearer ${token}` } }
); );

View File

@ -19,7 +19,7 @@ export default function SchedulesPage() {
const fetchSchedules = async () => { const fetchSchedules = async () => {
try { try {
const token = localStorage.getItem("token"); const token = localStorage.getItem("token");
const res = await axios.get("http://localhost:8080/api/schedules", { const res = await axios.get("http://172.17.110.6:8080/api/schedules", {
headers: { Authorization: `Bearer ${token}` } headers: { Authorization: `Bearer ${token}` }
}); });
setSchedules(res.data.data || []); setSchedules(res.data.data || []);

View File

@ -22,7 +22,7 @@ export default function AddBookingPage() {
const fetchRooms = async () => { const fetchRooms = async () => {
try { try {
const token = localStorage.getItem("token"); const token = localStorage.getItem("token");
const res = await axios.get("http://localhost:8080/api/rooms", { const res = await axios.get("http://172.17.110.6:8080/api/rooms", {
headers: { Authorization: `Bearer ${token}` }, headers: { Authorization: `Bearer ${token}` },
}); });
setRooms(res.data.data); setRooms(res.data.data);
@ -46,7 +46,7 @@ export default function AddBookingPage() {
const startISO = new Date(startTime).toISOString(); const startISO = new Date(startTime).toISOString();
const endISO = new Date(endTime).toISOString(); const endISO = new Date(endTime).toISOString();
await axios.post("http://localhost:8080/api/bookings", { await axios.post("http://172.17.110.6:8080/api/bookings", {
room_id: parseInt(selectedRoomId), room_id: parseInt(selectedRoomId),
start_time: startISO, start_time: startISO,
end_time: endISO, end_time: endISO,

View File

@ -58,9 +58,9 @@ export default function CalendarViewPage() {
const token = localStorage.getItem("token"); const token = localStorage.getItem("token");
// 2. FETCH DATA SCHEDULES BERSAMAAN DENGAN ROOMS & BOOKINGS // 2. FETCH DATA SCHEDULES BERSAMAAN DENGAN ROOMS & BOOKINGS
const [roomsRes, bookingsRes, schedulesRes] = await Promise.all([ const [roomsRes, bookingsRes, schedulesRes] = await Promise.all([
axios.get("http://localhost:8080/api/rooms", { headers: { Authorization: `Bearer ${token}` } }), axios.get("http://172.17.110.6:8080/api/rooms", { headers: { Authorization: `Bearer ${token}` } }),
axios.get("http://localhost:8080/api/bookings", { headers: { Authorization: `Bearer ${token}` } }), axios.get("http://172.17.110.6:8080/api/bookings", { headers: { Authorization: `Bearer ${token}` } }),
axios.get("http://localhost:8080/api/schedules", { headers: { Authorization: `Bearer ${token}` } }) axios.get("http://172.17.110.6:8080/api/schedules", { headers: { Authorization: `Bearer ${token}` } })
]); ]);
setRooms(roomsRes.data.data || []); setRooms(roomsRes.data.data || []);

View File

@ -45,7 +45,7 @@ export default function Dashboard() {
const fetchRooms = async (token: string) => { const fetchRooms = async (token: string) => {
try { try {
const response = await axios.get("http://localhost:8080/api/rooms", { const response = await axios.get("http://172.17.110.6:8080/api/rooms", {
headers: { Authorization: `Bearer ${token}` }, headers: { Authorization: `Bearer ${token}` },
}); });
setRooms(response.data.data); setRooms(response.data.data);
@ -79,7 +79,7 @@ export default function Dashboard() {
const endISO = new Date(endTime).toISOString(); const endISO = new Date(endTime).toISOString();
await axios.post( await axios.post(
"http://localhost:8080/api/bookings", "http://172.17.110.6:8080/api/bookings",
{ {
room_id: selectedRoom?.room_id, room_id: selectedRoom?.room_id,
start_time: startISO, start_time: startISO,

View File

@ -36,7 +36,7 @@ export default function HistoryPage() {
const fetchHistory = async (token: string) => { const fetchHistory = async (token: string) => {
try { try {
// PERBAIKAN: Ubah /api/bookings menjadi /api/my-bookings // PERBAIKAN: Ubah /api/bookings menjadi /api/my-bookings
const response = await axios.get("http://localhost:8080/api/my-bookings", { const response = await axios.get("http://172.17.110.6:8080/api/my-bookings", {
headers: { Authorization: `Bearer ${token}` }, headers: { Authorization: `Bearer ${token}` },
}); });
setBookings(response.data.data || []); setBookings(response.data.data || []);

View File

@ -22,18 +22,22 @@ export default function LoginPage() {
setError(""); setError("");
try { try {
// Tembak API Backend Golang // Tembak API Backend Golang menggunakan IP Laptop
// Opsional: Kamu bisa mengirimkan loginRole juga ke backend jika API-mu membutuhkannya const response = await axios.post("http://172.17.110.6:8080/api/auth/login", {
const response = await axios.post("http://localhost:8080/api/auth/login", {
nrp_nip: nrp, nrp_nip: nrp,
password: password, password: password,
// role_attempt: loginRole // Buka komentar ini jika backend Golang minta parameter role // role_attempt: loginRole // Buka komentar ini jika backend Golang minta parameter role
}); });
const { token, user } = response.data; const { token, user } = response.data;
// 1. Simpan di localStorage (untuk dipakai di axios frontend)
localStorage.setItem("token", token); localStorage.setItem("token", token);
localStorage.setItem("user", JSON.stringify(user)); localStorage.setItem("user", JSON.stringify(user));
// 2. Simpan di Cookie agar bisa dibaca oleh middleware.ts Next.js
document.cookie = `token=${token}; path=/; max-age=86400; SameSite=Lax`;
// Redirect berdasarkan role dari backend DAN pilihan di UI // Redirect berdasarkan role dari backend DAN pilihan di UI
if (user.role === "admin" && loginRole === "admin") { if (user.role === "admin" && loginRole === "admin") {
router.push("/admin"); router.push("/admin");
@ -43,6 +47,7 @@ export default function LoginPage() {
// Mencegah user biasa login lewat tab admin, atau sebaliknya // Mencegah user biasa login lewat tab admin, atau sebaliknya
setError("Role tidak sesuai dengan tipe akun Anda."); setError("Role tidak sesuai dengan tipe akun Anda.");
localStorage.clear(); // Bersihkan token yang terlanjur masuk localStorage.clear(); // Bersihkan token yang terlanjur masuk
document.cookie = "token=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT"; // Hapus cookie
} }
} catch (err: any) { } catch (err: any) {