diff --git a/package.json b/package.json index 1dd740f..fc6dd0f 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "version": "0.0.0", "type": "module", "scripts": { - "dev": "vite", + "dev": "vite --host", "build": "vite build", "lint": "eslint .", "preview": "vite preview", diff --git a/src/App.css b/src/App.css index d1e5037..36bb362 100644 --- a/src/App.css +++ b/src/App.css @@ -1,40 +1,78 @@ /* Navbar styling jika diperlukan */ body { - padding-top: 56px; /* Sesuaikan dengan tinggi Navbar */ - padding-left: 250px; /* Sesuaikan dengan tinggi Navbar */ + font-family: 'Poppins', sans-serif !important; + transition: background-color 0.3s, color 0.3s; + padding-top: 70px; /* Sesuaikan dengan tinggi Navbar */ + padding-left: 250px; } -.navbar { - background-color: #ffffff !important; +body.light { + background-color: #ffffff; + color: #1d1d1d; +} + +body.dark { + background-color: #161616; + color: #ffffff; +} + +.navbar-app { + display: flex; + justify-content: space-between; + align-items: center; padding-top: 10px; padding-bottom: 10px; - font-family: 'Poppins', sans-serif !important; } -/* Tambahan untuk Bootstrap override */ -.bg-light { - background-color: #f1f1f1 !important; +.light.navbar-app { + background-color: #ffffff; + transition: background-color 0.3s, color 0.3s; } -.text-dark { - color: #fff !important; +.light.navbar-brand { + color: #161616; + transition: background-color 0.3s, color 0.3s; +} + +.dark.navbar-app { + background-color: #161616; + transition: background-color 0.3s, color 0.3s; +} + +.dark.navbar-brand { + transition: background-color 0.3s, color 0.3s; + color: #ffffff; +} + +button { + padding: 4px 8px; + border: none; + cursor: pointer; + background-color: #474747; + color: white; + border-radius: 4px; +} + +button:hover { + opacity: 0.8; } /* Styling Sidebar */ -.sidebar { +.sidebar-app { width: 250px; height: 100vh; position: fixed; left: 0; top: 0; - padding-top: 75px; - overflow-y: auto; - border-right: 1px solid #ddd;/* Warna sidebar */ + padding-top: 100px; + overflow-y: auto; + transition: background-color 0.3s, color 0.3s; + /* border-right: 1px solid #414141; */ } /* Styling Default Link */ -.sidebar .nav-link { - margin: 0 15px 0 15px; +.sidebar-app .nav-link { + margin: 5px 15px; font-size: 16px; padding: 12px 15px; border-radius: 5px; @@ -43,16 +81,13 @@ body { } /* Hover Effect */ -.sidebar .nav-link:hover { +.sidebar-app .nav-link:hover { background-color: rgba(255, 255, 255, 0.2); } /* Halaman yang aktif */ -.sidebar .nav-link.active { - background-color:rgb(65, 157, 255); /* Warna biru saat aktif */ +.sidebar-app .nav-link.active { + background-color:rgb(71, 71, 71); /* Warna biru saat aktif */ color: white !important; font-weight: bold; } - - - diff --git a/src/App.jsx b/src/App.jsx index 1537934..36f9971 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -6,29 +6,39 @@ import Dashboard from './pages/Dashboard'; import DevicesPage from './pages/DevicesPage'; import ReportPage from "./pages/ReportPage"; import SettingsPage from "./pages/SettingsPage"; +import { useEffect, useState } from "react"; import './App.css'; function App() { + + const [theme, setTheme] = useState(localStorage.getItem("theme") || "light"); + + useEffect(() => { + document.body.className = theme; + localStorage.setItem("theme", theme); + }, [theme]); + + const toggleTheme = () => { + setTheme(prevTheme => (prevTheme === "light" ? "dark" : "light")); + }; + return ( -
- -
- -
- - } /> - } /> - } /> - } /> - } /> - -
+
+ + +
+ + }/> + }/> + }/> + }/> + }/> +
-
+
); } export default App; - diff --git a/src/components/charts/DownloadChart.jsx b/src/components/charts/DownloadChart.jsx index 4fd1c37..ffc5bdf 100644 --- a/src/components/charts/DownloadChart.jsx +++ b/src/components/charts/DownloadChart.jsx @@ -15,37 +15,37 @@ const DownloadChart = ({ data }) => { chart: { height: 250, type: 'area', - background: '#ececec', + background: '#1e1e1e', toolbar: { show: false }, }, dataLabels: { enabled: false }, stroke: { curve: 'smooth', - colors: ['#28a745'], + colors: ['#4CAF50'], }, xaxis: { type: 'datetime', - labels: { style: { fontFamily: 'Poppins, sans-serif' } }, - axisBorder: { color: '#555555' }, - axisTicks: { color: '#555555' }, + labels: { style: { fontFamily: 'Poppins, sans-serif', colors: '#ffffff' } }, + axisBorder: { color: '#777777' }, + axisTicks: { color: '#777777' }, }, yaxis: { - labels: { style: { fontFamily: 'Poppins, sans-serif' } }, + labels: { style: { fontFamily: 'Poppins, sans-serif', colors: '#ffffff' } }, }, grid: { - borderColor: '#555555', + borderColor: '#777777', strokeDashArray: 4, }, tooltip: { - theme: 'light', + theme: 'dark', x: { format: 'dd/MM/yy HH:mm' }, y: { formatter: (val) => `${val} Mbps` }, }, - colors: ['#28a745'], + colors: ['#4CAF50'], fill: { type: 'gradient', gradient: { - shade: 'light', + shade: 'dark', type: 'vertical', gradientToColors: ['#28a745'], stops: [0, 100], diff --git a/src/components/charts/PingChart.jsx b/src/components/charts/PingChart.jsx index 27e2d60..2b061b0 100644 --- a/src/components/charts/PingChart.jsx +++ b/src/components/charts/PingChart.jsx @@ -16,7 +16,7 @@ const PingChart = ({ data }) => { chart: { height: 250, type: 'area', - background: '#ececec', + background: '#1e1e1e', toolbar: { show: false }, }, dataLabels: { enabled: false }, @@ -26,15 +26,15 @@ const PingChart = ({ data }) => { }, xaxis: { type: 'datetime', - labels: { style: { fontFamily: 'Poppins, sans-serif' } }, - axisBorder: { color: '#555555' }, - axisTicks: { color: '#555555' }, + labels: { style: { fontFamily: 'Poppins, sans-serif', colors: '#ffffff' } }, + axisBorder: { color: '#777777' }, + axisTicks: { color: '#777777' }, }, yaxis: { - labels: { style: { fontFamily: 'Poppins, sans-serif' } }, + labels: { style: { fontFamily: 'Poppins, sans-serif', colors: '#ffffff' } }, }, grid: { - borderColor: '#555555', + borderColor: '#777777', strokeDashArray: 4, }, tooltip: { diff --git a/src/components/charts/UploadChart.jsx b/src/components/charts/UploadChart.jsx index 245b7f0..dd889a7 100644 --- a/src/components/charts/UploadChart.jsx +++ b/src/components/charts/UploadChart.jsx @@ -15,7 +15,7 @@ const UploadChart = ({ data }) => { chart: { height: 250, type: 'area', - background: '#ececec', + background: '#1e1e1e', toolbar: { show: false }, }, dataLabels: { enabled: false }, @@ -25,15 +25,15 @@ const UploadChart = ({ data }) => { }, xaxis: { type: 'datetime', - labels: { style: { fontFamily: 'Poppins, sans-serif' } }, - axisBorder: { color: '#555555' }, - axisTicks: { color: '#555555' }, + labels: { style: { fontFamily: 'Poppins, sans-serif', colors: '#ffffff' } }, + axisBorder: { color: '#777777' }, + axisTicks: { color: '#777777' }, }, yaxis: { - labels: { style: { fontFamily: 'Poppins, sans-serif' } }, + labels: { style: { fontFamily: 'Poppins, sans-serif', colors: '#ffffff' } }, }, grid: { - borderColor: '#555555', + borderColor: '#777777', strokeDashArray: 4, }, tooltip: { diff --git a/src/components/dashboard/AppDevice.jsx b/src/components/dashboard/AppDevice.jsx index f6d0885..7c77108 100644 --- a/src/components/dashboard/AppDevice.jsx +++ b/src/components/dashboard/AppDevice.jsx @@ -5,7 +5,7 @@ import { FaCheckCircle, FaTimesCircle } from "react-icons/fa"; const AppDevice = ({ devices }) => { return ( <> - +
diff --git a/src/components/dashboard/AverageData.jsx b/src/components/dashboard/AverageData.jsx index 7fe59c8..00a6326 100644 --- a/src/components/dashboard/AverageData.jsx +++ b/src/components/dashboard/AverageData.jsx @@ -24,7 +24,7 @@ const AverageData = ({ data }) => { return ( - + Average Download @@ -35,7 +35,7 @@ const AverageData = ({ data }) => { - + Average Upload @@ -46,7 +46,7 @@ const AverageData = ({ data }) => { - + Average Ping diff --git a/src/components/dashboard/ChartData.jsx b/src/components/dashboard/ChartData.jsx index 82fd2bc..ea0b9ea 100644 --- a/src/components/dashboard/ChartData.jsx +++ b/src/components/dashboard/ChartData.jsx @@ -5,12 +5,12 @@ import UploadChart from '../charts/UploadChart'; import PingChart from '../charts/PingChart'; import { FaDownload, FaUpload, FaTachometerAlt } from 'react-icons/fa'; -const Chart = ({ data }) => { +const Chart = ({ data, theme }) => { return ( <> - + @@ -21,7 +21,7 @@ const Chart = ({ data }) => { - + @@ -32,7 +32,7 @@ const Chart = ({ data }) => { - + diff --git a/src/components/dashboard/LatestData.jsx b/src/components/dashboard/LatestData.jsx index 6fe0b11..de2b5f5 100644 --- a/src/components/dashboard/LatestData.jsx +++ b/src/components/dashboard/LatestData.jsx @@ -2,21 +2,21 @@ import { FaDownload, FaUpload, FaTachometerAlt } from 'react-icons/fa'; import { Card, Col, Row } from 'react-bootstrap'; -const LatestData = ({ data }) => { +const LatestData = ({ data, theme }) => { const latestData = data.length > 0 ? data[data.length - 20] : null; if (!latestData) return null; return ( - +

Latest Data

- + Latest Download @@ -27,7 +27,7 @@ const LatestData = ({ data }) => { - + Latest Upload @@ -38,7 +38,7 @@ const LatestData = ({ data }) => { - + Latest Ping diff --git a/src/components/dashboard/MetricsTable.jsx b/src/components/dashboard/MetricsTable.jsx index 18e17b6..a254fa8 100644 --- a/src/components/dashboard/MetricsTable.jsx +++ b/src/components/dashboard/MetricsTable.jsx @@ -2,10 +2,10 @@ import Table from 'react-bootstrap/Table'; const MetricsTable = ({ metrics = [] }) => { return ( -
-
IP Address
+
+
- + @@ -16,9 +16,9 @@ const MetricsTable = ({ metrics = [] }) => { {metrics.map((item, index) => ( - + - +
Monitor Name URL Response Time (ms)
{item.monitor_name}{item.monitor_url}{item.monitor_url} {item.response_time} ms {item.status === 1 ? 'UP' : diff --git a/src/components/dashboard/TableData.jsx b/src/components/dashboard/TableData.jsx index 18ddf51..107d0d8 100644 --- a/src/components/dashboard/TableData.jsx +++ b/src/components/dashboard/TableData.jsx @@ -3,11 +3,11 @@ import { Table } from 'react-bootstrap'; import { format } from 'date-fns'; import { FaDownload, FaUpload, FaTachometerAlt } from "react-icons/fa"; -const DataTable = ({ data = [] }) => { +const DataTable = ({ data = [], theme }) => { return ( -
- - +
+
+

Dashboard

diff --git a/src/pages/DevicesPage.jsx b/src/pages/DevicesPage.jsx index 59ade40..938478a 100644 --- a/src/pages/DevicesPage.jsx +++ b/src/pages/DevicesPage.jsx @@ -35,9 +35,8 @@ function DevicesPage() { if (loading) { return ( - - -

Loading...

+ + ); } diff --git a/src/services/api.jsx b/src/services/api.jsx index 4de6f44..2e91dd6 100644 --- a/src/services/api.jsx +++ b/src/services/api.jsx @@ -1,14 +1,14 @@ import axios from 'axios'; -const API_URL = import.meta.env.VITE_API_URL; -const API_JSON_URL = import.meta.env.VITE_API_JSON_URL; +const API_SPEED_URL = import.meta.env.VITE_API_SPEED_URL; +const API_PING_URL = import.meta.env.VITE_API_PING_URL; const API_METRICS_URL = import.meta.env.VITE_API_METRICS_URL; // console.log(import.meta.env.VITE_API_URL) export const fetchSpeedTestData = async () => { try { - const response = await axios.get(API_URL, { + const response = await axios.get(API_SPEED_URL, { headers: { 'Author': 'vedeom', }, @@ -26,7 +26,7 @@ export const fetchSpeedTestData = async () => { export const fetchActiveDevices = async () => { try { - const response = await axios.get(API_JSON_URL); + const response = await axios.get(API_PING_URL); // console.log('Devices API Response:', response.data); diff --git a/vite.config.js b/vite.config.js index e559801..34dafc4 100644 --- a/vite.config.js +++ b/vite.config.js @@ -2,5 +2,9 @@ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' export default defineConfig({ - plugins: [react()] + plugins: [react()], + server: { + host: '0.0.0.0', + port: 5173, + } });
No diff --git a/src/components/layout/Navbar.jsx b/src/components/layout/Navbar.jsx index d497fca..dad161c 100644 --- a/src/components/layout/Navbar.jsx +++ b/src/components/layout/Navbar.jsx @@ -1,30 +1,20 @@ -import { Navbar, Nav} from 'react-bootstrap'; -import { FaChartLine } from 'react-icons/fa'; +import { Navbar, Nav } from 'react-bootstrap'; +import { FaChartLine, FaSun, FaMoon } from 'react-icons/fa'; -const AppNavbar = () => { +const AppNavbar = ({ toggleTheme, theme }) => { return ( - + - Speedtest Tracker + Speedtest Tracker -