diff --git a/src/components/Filters/FilterButtons.jsx b/src/components/Filters/FilterButtons.jsx index e7846e9..12d1ef1 100644 --- a/src/components/Filters/FilterButtons.jsx +++ b/src/components/Filters/FilterButtons.jsx @@ -1,11 +1,6 @@ import React from "react"; import "../../styles/filters.css"; -/** - * Vertical glossy filter buttons for the main categories. - * active: string in { "All", "News", "Friends", "Events", "Market" } - * onSelect(code): called with the category code. - */ export default function FilterButtons({ active, onSelect }) { const buttons = [ { code: "All", label: "All", icon: "fa-solid fa-globe" }, @@ -16,19 +11,21 @@ export default function FilterButtons({ active, onSelect }) { ]; return ( -
+
{buttons.map((btn) => ( ))}
diff --git a/src/components/Filters/TimeFilterButtons.jsx b/src/components/Filters/TimeFilterButtons.jsx new file mode 100644 index 0000000..fb415ed --- /dev/null +++ b/src/components/Filters/TimeFilterButtons.jsx @@ -0,0 +1,32 @@ +import React from "react"; +import "../../styles/filters.css"; + +export default function TimeFilterButtons({ active, onSelect }) { + const buttons = [ + { code: "NOW", label: "Now", icon: "fa-solid fa-bolt" }, + { code: "TODAY", label: "Today", icon: "fa-solid fa-sun" }, + { code: "RECENT", label: "Recent", icon: "fa-solid fa-clock-rotate-left" }, + { code: "PAST", label: "Past", icon: "fa-solid fa-hourglass-half" }, + ]; + + return ( +
+ {buttons.map((btn) => ( + + ))} +
+ ); +} diff --git a/src/components/Map/MapView.jsx b/src/components/Map/MapView.jsx index 7ac8479..08c2e2f 100644 --- a/src/components/Map/MapView.jsx +++ b/src/components/Map/MapView.jsx @@ -17,6 +17,7 @@ import { usePostsEngine } from "./usePostsEngine"; import PostList from "../Posts/PostList"; import { useAuth } from "../../auth/AuthContext"; import FilterButtons from "../Filters/FilterButtons"; +import TimeFilterButtons from "../Filters/TimeFilterButtons"; export default function MapView({ theme = "dark" }) { const { authenticated, username, token } = useAuth(); @@ -95,7 +96,7 @@ export default function MapView({ theme = "dark" }) { handleIncomingPost(msg.post); } } catch { - // ignore bad messages + // ignore } }; return () => ws && ws.close(); @@ -139,7 +140,7 @@ export default function MapView({ theme = "dark" }) { const authorName = (username || "").trim() || "anon"; - // Crosshair offset: adjust so big bubble sits correctly above pointer + // Crosshair offset so the big bubble appears above the pointer let baseLng; let baseLat; @@ -152,7 +153,7 @@ export default function MapView({ theme = "dark" }) { baseLat = center.lat; } - const pixelOffsetY = -20; // tweak if needed + const pixelOffsetY = -20; const screenPoint = map.project([baseLng, baseLat]); const correctedPoint = { @@ -184,7 +185,6 @@ export default function MapView({ theme = "dark" }) { token ); - // Inject directly into the posts engine in addition to WebSocket broadcast if (newPost && newPost.id) { handleIncomingPost(newPost); } @@ -209,7 +209,6 @@ export default function MapView({ theme = "dark" }) { } }; - // Map right-side category selection from FilterButtons const handleMainFilterSelect = (code) => { if (!FILTER_MAIN_CATEGORIES.includes(code)) return; setMainFilter(code); @@ -230,45 +229,39 @@ export default function MapView({ theme = "dark" }) {
- {/* LEFT (time filters) */} + {/* LEFT: time filters as icon+label */}
- {[ - ["NOW", "Now"], - ["TODAY", "Today"], - ["RECENT", "Recently"], - ["PAST", "Past"], - ].map(([code, label]) => ( - - ))} + setTimeFilter(code)} + />
- {/* RIGHT (main categories with glossy icons) */} + {/* RIGHT: main categories as icon+label */}
- +
- {/* BOTTOM (subcategories glossy pills) */} + {/* BOTTOM: subcategories icons */}
-
+
{bottomCategories.map((c) => ( ))}
diff --git a/src/styles/filters.css b/src/styles/filters.css index 97f5382..1f4ad77 100644 --- a/src/styles/filters.css +++ b/src/styles/filters.css @@ -1,80 +1,126 @@ -/* ===== SocioWire glossy filter buttons ===== */ +/* ===== Generic vertical icon column (right & left) ===== */ -/* Vertical circular category buttons (right side) */ -.sw-filter-column { +.sw-icon-column { display: flex; flex-direction: column; - gap: 0.6rem; + gap: 0.55rem; + align-items: center; } -.sw-filter-btn { - width: 70px; - height: 70px; - border-radius: 50%; - background: radial-gradient(circle at 30% 30%, #38bdf8, #1d4ed8, #020617); - border: 2px solid rgba(255,255,255,0.2); - box-shadow: 0 4px 14px rgba(0,0,0,0.7); +.sw-icon-btn { + background: none; + border: none; + padding: 0; + cursor: pointer; display: flex; flex-direction: column; align-items: center; + gap: 0.15rem; + color: #e5e7eb; +} + +.sw-icon-circle { + width: 54px; + height: 54px; + border-radius: 50%; + background: rgba(15, 23, 42, 0.86); + border: 1.5px solid rgba(148, 163, 184, 0.7); + display: flex; + align-items: center; justify-content: center; - color: #e5f0ff; - cursor: pointer; - transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease; + box-shadow: 0 3px 10px rgba(0, 0, 0, 0.75); + transition: + transform 0.12s ease, + box-shadow 0.12s ease, + border-color 0.12s ease, + background 0.12s ease; } -.sw-filter-btn i { - font-size: 24px; - margin-bottom: 2px; +.sw-icon-circle i { + font-size: 22px; } -.sw-filter-label { +.sw-icon-label { font-size: 0.7rem; line-height: 1; - text-shadow: 0 1px 2px rgba(0,0,0,0.9); + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.9); } -.sw-filter-btn:hover { - transform: translateY(-3px); - box-shadow: 0 7px 20px rgba(0,0,0,0.8); +.sw-icon-btn:hover .sw-icon-circle { + transform: translateY(-1px); + box-shadow: 0 5px 14px rgba(0, 0, 0, 0.85); } -.sw-filter-active { - border-color: #38bdf8; - box-shadow: 0 0 18px rgba(56,189,248,0.9); +.sw-icon-btn:active .sw-icon-circle { + transform: scale(0.96); + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.9); } -/* ===== Bottom sub-category glossy pills ===== */ - -.sw-bottom-bar { - display: flex; - gap: 0.4rem; - padding: 0.2rem 0.6rem; - background: radial-gradient(circle at 0% 0%, rgba(15,23,42,0.96), rgba(15,23,42,0.85)); - border-radius: 999px; - box-shadow: 0 4px 16px rgba(0,0,0,0.75); +/* active state: same color for icon + background, more glow */ +.sw-icon-active .sw-icon-circle { + background: rgba(37, 99, 235, 0.82); + border-color: #60a5fa; + box-shadow: 0 0 14px rgba(56, 189, 248, 0.95); } -.sw-bottom-btn { - border-radius: 999px; - padding: 0.25rem 0.75rem; - font-size: 0.75rem; - border: 1px solid rgba(148,163,184,0.6); - background: rgba(15,23,42,0.9); - color: #e5e7eb; - cursor: pointer; - white-space: nowrap; - transition: background .12s ease, transform .12s ease, box-shadow .12s ease; -} - -.sw-bottom-btn:hover { - transform: translateY(-2px); - box-shadow: 0 4px 10px rgba(0,0,0,0.7); -} - -.sw-bottom-btn-active { - background: linear-gradient(135deg, #38bdf8, #1d4ed8); - border-color: #93c5fd; - color: #0b1120; +.sw-icon-active .sw-icon-label { + color: #bfdbfe; + font-weight: 600; +} + +/* ===== Bottom sub-category icons (row) ===== */ + +.sw-bottom-row { + display: flex; + gap: 0.35rem; + padding: 0.2rem 0.6rem; + background: rgba(15, 23, 42, 0.94); + border-radius: 999px; + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.85); +} + +.sw-bottom-item { + border: none; + background: none; + padding: 0; + cursor: pointer; + display: flex; + flex-direction: column; + align-items: center; + gap: 0.12rem; + min-width: 54px; +} + +.sw-bottom-circle { + width: 40px; + height: 40px; + border-radius: 50%; + background: rgba(15, 23, 42, 0.86); + border: 1.5px solid rgba(148, 163, 184, 0.6); + display: flex; + align-items: center; + justify-content: center; + font-size: 0.78rem; + box-shadow: 0 3px 10px rgba(0, 0, 0, 0.75); +} + +.sw-bottom-label { + font-size: 0.65rem; + color: #e5e7eb; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.9); +} + +.sw-bottom-item:hover .sw-bottom-circle { + transform: translateY(-1px); + box-shadow: 0 5px 14px rgba(0, 0, 0, 0.85); +} + +.sw-bottom-active .sw-bottom-circle { + background: rgba(37, 99, 235, 0.82); + border-color: #60a5fa; +} + +.sw-bottom-active .sw-bottom-label { + color: #bfdbfe; font-weight: 600; }