diff --git a/frontend/src/App.css b/frontend/src/App.css
index b9d355d..9d75ae7 100644
--- a/frontend/src/App.css
+++ b/frontend/src/App.css
@@ -1,42 +1,10 @@
+html,
+body,
#root {
- max-width: 1280px;
- margin: 0 auto;
- padding: 2rem;
- text-align: center;
+ height: 100%;
+ width: 100%;
}
-.logo {
- height: 6em;
- padding: 1.5em;
- will-change: filter;
- transition: filter 300ms;
-}
-.logo:hover {
- filter: drop-shadow(0 0 2em #646cffaa);
-}
-.logo.react:hover {
- filter: drop-shadow(0 0 2em #61dafbaa);
-}
-
-@keyframes logo-spin {
- from {
- transform: rotate(0deg);
- }
- to {
- transform: rotate(360deg);
- }
-}
-
-@media (prefers-reduced-motion: no-preference) {
- a:nth-of-type(2) .logo {
- animation: logo-spin infinite 20s linear;
- }
-}
-
-.card {
- padding: 2em;
-}
-
-.read-the-docs {
- color: #888;
-}
+body {
+ margin: 0;
+}
\ No newline at end of file
diff --git a/frontend/src/pages/Stats.tsx b/frontend/src/pages/Stats.tsx
index b487204..63fdf8b 100644
--- a/frontend/src/pages/Stats.tsx
+++ b/frontend/src/pages/Stats.tsx
@@ -12,6 +12,7 @@ import {
import ActivityHeatmap from "../stats/ActivityHeatmap";
import { ReactWordcloud } from '@cp949/react-wordcloud';
+import StatsStyling from "../styles/stats_styling";
type BackendWord = {
word: string;
@@ -24,6 +25,8 @@ type TopUser = {
count: number;
};
+const styles = StatsStyling;
+
const StatPage = () => {
const [error, setError] = useState('');
const [loading, setLoading] = useState(true);
@@ -110,89 +113,111 @@ const StatPage = () => {
getStats();
}, [])
- if (loading) return
Loading insights…
;
- if (error) return {error}
;
+ if (loading) return Loading insights…
;
+ if (error) return {error}
;
- return (
-
-
-
+
+
+
-
-
+
-
+
+
-
-
Events per Day
+
Analytics Dashboard
+
-
+ {/* main grid*/}
+
+ {/* events per day */}
+
+
Events per Day
+
Trend of activity over time
+
+
+
-
+
+
-
-
Word Cloud
-
+ Word Cloud
+ Most common terms across events
+
+
+
+
- {topUserData?.length > 0 && (
-
-
Top Users
+ {/* Top Users */}
+ {topUserData?.length > 0 && (
+
+
Top Users
+
Most active authors
+
+
{topUserData.map((item) => (
-
- {item.author} ({item.source}): {item.count}
-
+
+
{item.author}
+
+ {item.source} • {item.count} events
+
+
))}
- )}
-
+ )}
-
-
Heatmap
-
+ {/* Heatmap */}
+
+
Heatmap
+
Activity density across time
+
+
- );
+
+);
}
-export default StatPage;
+export default StatPage;
\ No newline at end of file
diff --git a/frontend/src/styles/stats_styling.tsx b/frontend/src/styles/stats_styling.tsx
new file mode 100644
index 0000000..ed82869
--- /dev/null
+++ b/frontend/src/styles/stats_styling.tsx
@@ -0,0 +1,134 @@
+import type { CSSProperties } from "react";
+
+const StatsStyling: Record
= {
+ page: {
+ width: "100%",
+ height: "100%",
+ minHeight: "100vh",
+ minWidth: "100vh",
+ padding: 24,
+ background: "#f6f7fb",
+ fontFamily:
+ '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Inter, Arial, sans-serif',
+ color: "#111827",
+ },
+
+ container: {
+ maxWidth: 1400,
+ margin: "0 auto",
+ },
+
+ card: {
+ background: "white",
+ borderRadius: 16,
+ padding: 16,
+ border: "1px solid rgba(0,0,0,0.06)",
+ boxShadow: "0 6px 20px rgba(0,0,0,0.06)",
+ },
+
+ headerBar: {
+ display: "flex",
+ flexWrap: "wrap",
+ alignItems: "center",
+ justifyContent: "space-between",
+ gap: 12,
+ },
+
+ controls: {
+ display: "flex",
+ gap: 10,
+ alignItems: "center",
+ },
+
+ input: {
+ width: 320,
+ maxWidth: "70vw",
+ padding: "10px 12px",
+ borderRadius: 12,
+ border: "1px solid rgba(0,0,0,0.12)",
+ outline: "none",
+ fontSize: 14,
+ background: "#fff",
+ color: "black"
+ },
+
+ buttonPrimary: {
+ padding: "10px 14px",
+ borderRadius: 12,
+ border: "1px solid rgba(0,0,0,0.08)",
+ background: "#2563eb",
+ color: "white",
+ fontWeight: 600,
+ cursor: "pointer",
+ boxShadow: "0 6px 16px rgba(37,99,235,0.25)",
+ },
+
+ buttonSecondary: {
+ padding: "10px 14px",
+ borderRadius: 12,
+ border: "1px solid rgba(0,0,0,0.12)",
+ background: "#fff",
+ color: "#111827",
+ fontWeight: 600,
+ cursor: "pointer",
+ },
+
+ grid: {
+ marginTop: 18,
+ display: "grid",
+ gridTemplateColumns: "repeat(12, 1fr)",
+ gap: 16,
+ },
+
+ sectionTitle: {
+ margin: 0,
+ fontSize: 16,
+ fontWeight: 700,
+ },
+
+ sectionSubtitle: {
+ margin: "6px 0 14px",
+ fontSize: 13,
+ color: "#6b7280",
+ },
+
+ chartWrapper: {
+ width: "100%",
+ height: 350,
+ },
+
+ heatmapWrapper: {
+ width: "100%",
+ height: 320,
+ },
+
+ topUsersList: {
+ display: "flex",
+ flexDirection: "column",
+ gap: 10,
+ },
+
+ topUserItem: {
+ padding: "10px 12px",
+ borderRadius: 12,
+ background: "#f9fafb",
+ border: "1px solid rgba(0,0,0,0.06)",
+ },
+
+ topUserName: {
+ fontWeight: 700,
+ fontSize: 14,
+ },
+
+ topUserMeta: {
+ fontSize: 13,
+ color: "#6b7280",
+ },
+
+ scrollArea: {
+ maxHeight: 450,
+ overflowY: "auto",
+ },
+};
+
+export default StatsStyling;
\ No newline at end of file