diff --git a/src/admin/package.json b/src/admin/package.json index 56d07b1..303df87 100644 --- a/src/admin/package.json +++ b/src/admin/package.json @@ -11,8 +11,7 @@ "dependencies": { "axios": "^1.4.0", "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-router-dom": "^6.14.0" + "react-dom": "^18.2.0" }, "devDependencies": { "@types/react": "^19.1.10", diff --git a/src/admin/src/App.tsx b/src/admin/src/App.tsx index 7797b61..b972969 100644 --- a/src/admin/src/App.tsx +++ b/src/admin/src/App.tsx @@ -1,43 +1,109 @@ -import React from "react"; -import { NavLink, Routes, Route, useNavigate } from "react-router-dom"; -import Dashboard from "./pages/Dashboard"; -import Send from "./pages/Send"; -import Scheduling from "./pages/Scheduling"; -import Alerts from "./pages/Alerts"; -import Qr from "./pages/Qr"; - -const navClasses = ({ isActive }: { isActive: boolean }) => - `px-3 py-2 rounded-md text-sm font-medium ${isActive ? "bg-gray-700 text-white" : "text-gray-300 hover:bg-gray-700 hover:text-white"}`; +import React, { useEffect, useState } from "react"; export default function App() { + const [dark, setDark] = useState(true); + + useEffect(() => { + document.documentElement.classList.toggle("dark", dark); + }, [dark]); + + const navItems = ["Dashboard", "Messages", "Analytics", "Settings"]; + return ( -
- -
- - } /> - } /> - } /> - } /> - } /> - +
+ +
+
+

Dashboard

+ +
+ +
+
+

Sessions

+

8

+
+
+

Messages

+

1.2k

+
+
+

Deliveries

+

98%

+
+
+

Errors

+

2

+
+
+ +
+
+

Overview

+
+ + + +
+
+
+

Customers

+
    +
  • + + SJ + +
    +

    Sarah Johnson

    +

    Active

    +
    +
  • +
  • + + RB + +
    +

    Rahul B

    +

    Offline

    +
    +
  • +
  • + + MK + +
    +

    Maria K

    +

    Active

    +
    +
  • +
+
+
); } + diff --git a/src/admin/src/main.tsx b/src/admin/src/main.tsx index 8de1488..49aeb45 100644 --- a/src/admin/src/main.tsx +++ b/src/admin/src/main.tsx @@ -1,16 +1,12 @@ import React from "react"; import ReactDOM from "react-dom/client"; -import { BrowserRouter } from "react-router-dom"; import App from "./App"; -import "./styles.css"; const root = document.getElementById("root"); if (root) { ReactDOM.createRoot(root).render( - - - + , ); } diff --git a/src/admin/src/pages/Alerts.tsx b/src/admin/src/pages/Alerts.tsx deleted file mode 100644 index 29ee3b9..0000000 --- a/src/admin/src/pages/Alerts.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import React, { useEffect, useState } from "react"; -import { fetchHealth } from "../lib/api"; - -interface AlertItem { - ts: number; - message: string; -} - -export default function Alerts() { - const [alerts, setAlerts] = useState([]); - const [lastReady, setLastReady] = useState(null); - - useEffect(() => { - const interval = setInterval(check, 5000); - check(); - return () => clearInterval(interval); - }, []); - - async function check() { - try { - const health = await fetchHealth(); - if (lastReady === null) { - setLastReady(health.session.ready); - return; - } - if (health.session.ready !== lastReady) { - const message = health.session.ready - ? "Relinked / Ready" - : "QR required or offline"; - setAlerts((prev) => - [{ ts: Date.now(), message }, ...prev].slice(0, 20), - ); - setLastReady(health.session.ready); - } - } catch (err) { - console.error(err); - } - } - - return ( -
-

Alerts

-
    - {alerts.map((a) => ( -
  • -
    - {new Date(a.ts).toLocaleString()} -
    -
    {a.message}
    -
  • - ))} - {alerts.length === 0 &&

    No alerts yet.

    } -
-
- ); -} diff --git a/src/admin/src/pages/Dashboard.tsx b/src/admin/src/pages/Dashboard.tsx deleted file mode 100644 index fcd9388..0000000 --- a/src/admin/src/pages/Dashboard.tsx +++ /dev/null @@ -1,137 +0,0 @@ -import React, { useEffect, useState } from "react"; -import { fetchHealth, sendMessage, testPush, subscribePush } from "../lib/api"; - -interface Health { - session: { ready: boolean; qr: string | null }; - sentToday: number; - perMinAvailable: number; - dailyCap: number; - headless: boolean; -} - -export default function Dashboard() { - const [health, setHealth] = useState(null); - const [phone, setPhone] = useState(""); - const [text, setText] = useState(""); - const [disablePrefix, setDisablePrefix] = useState(false); - const [message, setMessage] = useState(null); - - useEffect(() => { - refresh(); - const id = setInterval(refresh, 5000); - return () => clearInterval(id); - }, []); - - async function refresh() { - try { - const data = await fetchHealth(); - setHealth(data); - } catch (err) { - console.error(err); - } - } - - async function handleSend(e: React.FormEvent) { - e.preventDefault(); - try { - await sendMessage({ phone, text, disablePrefix }); - setMessage("Message sent"); - setPhone(""); - setText(""); - } catch (err: any) { - setMessage(err.response?.data?.error || "Error sending"); - } - refresh(); - } - - async function handleSubscribe() { - if (!("serviceWorker" in navigator)) return; - const reg = await navigator.serviceWorker.ready; - const subscription = await reg.pushManager.subscribe({ - userVisibleOnly: true, - applicationServerKey: undefined, - }); - await subscribePush(subscription); - alert("Subscribed to push notifications"); - } - - return ( -
-

Dashboard

- {health && ( -
-
-
Session
-

{health.session.ready ? "Ready" : "Not ready"}

-
-
-
Daily Usage
-

- {health.sentToday} / {health.dailyCap} -

-
-
-
Minute Tokens
-

{health.perMinAvailable} available

-
-
-
Headless
-

{health.headless ? "Enabled" : "Disabled"}

-
-
- )} -
-

Quick Send

-
-
- setPhone(e.target.value)} - className="w-full px-3 py-2 rounded bg-gray-700 text-white" - /> -
-
-