Merge to main branch - #1
Merged
Merged
Conversation
…e chart and sidebar components
… logos, and activity API; update sidebar and dashboard components to integrate activity data
… add user session management and activity API
…oard alerts and controls
…new MenuIcon component
…tivity logging with error handling
…orresponding styles
There was a problem hiding this comment.
Pull request overview
This PR introduces the “NeoGate” codebase: a Next.js web app (landing page + login + dashboard + basic admin page) integrated with Firebase (Firestore + Realtime Database), along with an IoT Arduino sketch set and a Docusaurus “bukupanduan” documentation site.
Changes:
- Add Next.js app scaffolding (pages, views, styles, components) including dashboard + login flows.
- Add Firebase client utilities for authentication-like behavior and RTDB activity/status listeners, plus basic admin operator creation.
- Add Docusaurus documentation site and IoT ESP32 sketches.
Reviewed changes
Copilot reviewed 59 out of 74 changed files in this pull request and generated 13 comments.
Show a summary per file
| File | Description |
|---|---|
| ptt_2026/tsconfig.json | TypeScript config for Next.js app |
| ptt_2026/src/views/dashboard/index.tsx | Dashboard UI + RTDB listeners |
| ptt_2026/src/views/dashboard/dashboard.module.scss | Dashboard styling |
| ptt_2026/src/views/auth/login/index.tsx | Login UI + client sign-in call |
| ptt_2026/src/views/auth/auth.module.css | Auth page styling |
| ptt_2026/src/utils/db/firebaseService.ts | Firestore/RTDB helpers + “signIn”/operator creation |
| ptt_2026/src/utils/db/firebase.ts | Firebase initialization (app/auth/db/rtdb) |
| ptt_2026/src/styles/landingpage.module.css | Landing page styles |
| ptt_2026/src/styles/Home.module.css | Default Next.js home styles |
| ptt_2026/src/styles/globals.css | Global styles + local font faces |
| ptt_2026/src/styles/components/components.module.scss | Shared component styles (sidebar/table/cards/etc) |
| ptt_2026/src/pages/index.tsx | Landing page content |
| ptt_2026/src/pages/dashboard/index.tsx | Dashboard route wrapper |
| ptt_2026/src/pages/auth/login/index.tsx | Login route wrapper |
| ptt_2026/src/pages/api/hello.ts | Default example API route |
| ptt_2026/src/pages/api/aktivitas.ts | Firestore “aktivitas” API endpoint |
| ptt_2026/src/pages/api/admin/create-user.ts | Admin user creation API endpoint |
| ptt_2026/src/pages/admin/operators.tsx | Admin UI to create operators |
| ptt_2026/src/pages/_document.tsx | Custom Document |
| ptt_2026/src/pages/_app.tsx | Custom App + global CSS import |
| ptt_2026/src/middleware/withAuth.ts | NextAuth-based middleware helper (unused by current flow) |
| ptt_2026/src/middleware.ts | Cookie-based route gating middleware |
| ptt_2026/src/lib/auth.ts | LocalStorage/cookie “session” helpers |
| ptt_2026/src/components/sidebar.tsx | Sidebar navigation |
| ptt_2026/src/components/IoTAnimation.tsx | Landing page SVG animation component |
| ptt_2026/src/components/chart.tsx | Chart component |
| ptt_2026/src/components/card.tsx | Metric card component |
| ptt_2026/src/components/activityTable.tsx | Activity table component |
| ptt_2026/README.md | Default Next.js README |
| ptt_2026/public/vercel.svg | Static asset |
| ptt_2026/public/next.svg | Static asset |
| ptt_2026/package.json | Next.js app dependencies/scripts |
| ptt_2026/next.config.js | Next.js config |
| ptt_2026/.gitignore | App-level ignore rules |
| ptt_2026/.eslintrc.json | ESLint config |
| ptt_2026/.env | Environment variables (currently committed) |
| package.json | Root package.json placeholder |
| node_modules/.package-lock.json | Committed node_modules artifact |
| IoT/testing_PBLV3.ino | ESP32 sketch v3 |
| IoT/testing_PBLV2.ino | ESP32 sketch v2 |
| IoT/testing_PBLV1.ino | ESP32 sketch v1 |
| bukupanduan/tsconfig.json | Docusaurus TS config |
| bukupanduan/static/img/monitoring.svg | Docs asset |
| bukupanduan/static/img/logs.svg | Docs asset |
| bukupanduan/static/img/control.svg | Docs asset |
| bukupanduan/static/.nojekyll | GitHub Pages support |
| bukupanduan/src/pages/markdown-page.mdx | Example MDX page |
| bukupanduan/src/pages/index.tsx | Docusaurus home page |
| bukupanduan/src/pages/index.module.css | Docusaurus home styles |
| bukupanduan/src/css/custom.css | Docusaurus theme overrides |
| bukupanduan/src/components/HomepageFeatures/styles.module.css | Features component styles |
| bukupanduan/src/components/HomepageFeatures/index.tsx | Features component |
| bukupanduan/sidebars.ts | Docs sidebar config |
| bukupanduan/README.md | Docusaurus README |
| bukupanduan/package.json | Docusaurus dependencies/scripts |
| bukupanduan/docusaurus.config.ts | Docusaurus site configuration |
| bukupanduan/docs/troubleshooting.md | Docs content |
| bukupanduan/docs/monitoring.md | Docs content |
| bukupanduan/docs/logs.md | Docs content |
| bukupanduan/docs/logout.md | Docs content |
| bukupanduan/docs/login.md | Docs content |
| bukupanduan/docs/intro.md | Docs content |
| bukupanduan/docs/getting-started.md | Docs content |
| bukupanduan/docs/dashboard.md | Docs content |
| bukupanduan/docs/control.md | Docs content |
| bukupanduan/.gitignore | Docs site ignore rules |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+1
to
+10
| NEXT_PUBLIC_FIREBASE_API_KEY="AIzaSyAroSgC1WLQZaZAq3vwxun7MVtt4csIKeU" | ||
| NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN="neogate-e38cd.firebaseapp.com" | ||
| NEXT_PUBLIC_FIREBASE_DATABASE_URL="https://neogate-e38cd-default-rtdb.asia-southeast1.firebasedatabase.app" | ||
| NEXT_PUBLIC_FIREBASE_PROJECT_ID="neogate-e38cd" | ||
| NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET="neogate-e38cd.firebasestorage.app" | ||
| NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID="401110049602" | ||
| NEXT_PUBLIC_FIREBASE_APP_ID="1:401110049602:web:46d9180e85b40e8f739edb" | ||
| NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID="G-VS7C5YG0VW" | ||
| NEXTAUTH_URL="http://localhost:3000" | ||
| NEXTAUTH_SECRET="uExl/n3FZsMhXoA7cCAnBA9jzd2jtxK76uyPkUGXLIs=" No newline at end of file |
Comment on lines
+1
to
+6
| { | ||
| "name": "PTT2026", | ||
| "lockfileVersion": 3, | ||
| "requires": true, | ||
| "packages": {} | ||
| } |
Comment on lines
+21
to
+57
| export const signIn = async (email: string, pass: string) => { | ||
| try { | ||
| // 1. Cari user berdasarkan email | ||
| const q = query(usersCollection, where("email", "==", email.trim().toLowerCase())); | ||
| const snapshot = await getDocs(q); | ||
|
|
||
| if (snapshot.empty) return { status: false, message: "User kaga ada!" }; | ||
|
|
||
| const userDoc = snapshot.docs[0]; | ||
| const userData = userDoc.data(); | ||
|
|
||
| if (userData.isActive === false) { | ||
| return { status: false, message: "Akun nonaktif. Hubungi superadmin." }; | ||
| } | ||
|
|
||
| const role = userData.role || "operator"; | ||
| if (role !== "operator" && role !== "operator1" && role !== "operator2" && role !== "admin" && role !== "superadmin") { | ||
| return { status: false, message: "Role akun tidak valid." }; | ||
| } | ||
|
|
||
| // 2. Cek Password (Bandingin teks biasa sama yang di-hash) | ||
| const isMatch = bcrypt.compareSync(pass, userData.password); | ||
|
|
||
| if (isMatch) { | ||
| const userName = userData.name || userData.fullname || userData.fullName || userData.displayName; | ||
| const gate = userData.gate || getGateFromRole(role); | ||
|
|
||
| return { | ||
| status: true, | ||
| data: { id: userDoc.id, name: userName, email: userData.email, role, gate } | ||
| }; | ||
| } else { | ||
| return { status: false, message: "Password salah!" }; | ||
| } | ||
| } catch (error) { | ||
| return { status: false, message: error }; | ||
| } |
| import { addDoc, collection, getDocs, query, where } from "firebase/firestore"; | ||
| import bcrypt from "bcryptjs"; | ||
| import { rtdb } from "./firebase"; | ||
| import { ref, onValue, set, push, serverTimestamp } from "firebase/database"; |
| "@types/node": "25.6.0", | ||
| "@types/react": "19.2.14", | ||
| "@types/react-dom": "19.2.3", | ||
| "bcrypt": "^6.0.0", |
Comment on lines
+203
to
+206
| <span className={styles.profileGate}>{gateLabel}</span> | ||
| </div> | ||
| <div className={styles.avatar}>{userName[0]}</div> | ||
| </div> |
Comment on lines
+5
to
+14
| // Ambil tanda login dari cookie (karena middleware ga bisa baca localStorage) | ||
| const isLogin = request.cookies.get('isLogin')?.value | ||
|
|
||
| const { pathname } = request.nextUrl | ||
| if (!isLogin && (pathname.startsWith('/dashboard') || pathname.startsWith('/admin'))) { | ||
| return NextResponse.redirect(new URL('/auth/login', request.url)) | ||
| } | ||
| if (isLogin && pathname.startsWith('/auth')) { | ||
| return NextResponse.redirect(new URL('/dashboard', request.url)) | ||
| } |
Comment on lines
+1
to
+4
| import React, { useEffect, useState } from 'react' | ||
| import Image from 'next/image' | ||
| import Link from 'next/link' | ||
| import styles from '@/styles/components/components.module.scss' |
Comment on lines
+76
to
+80
| void tutupPalang(bool cekKendaraan) { | ||
| for (int i = pos; i <= 90; i++) { | ||
| n | ||
| if (digitalRead(vehicle1) == LOW || digitalRead(vehicle2) == LOW) { | ||
| Serial.println("DARURAT: Kendaraan terdeteksi! Berhenti menutup."); |
Comment on lines
+70
to
+79
| setIsSubmitting(true) | ||
| const sessionUser = getSessionUser() | ||
| const result = await createOperatorByAdmin({ | ||
| name, | ||
| email, | ||
| password, | ||
| gate, | ||
| createdBy: sessionUser?.email || userName | ||
| }) | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.