From c4a6c3cddc907c0a3aacb72069bf68f981bcf82d Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 10 Dec 2025 23:29:13 -0500 Subject: [PATCH] update frontend --- src/components/Filters/FilterButtons.jsx | 54 +++++++------ src/components/Map/MapView.jsx | 97 +++++++++++------------- src/styles/filters.css | 79 ++++++++++++++----- 3 files changed, 137 insertions(+), 93 deletions(-) diff --git a/src/components/Filters/FilterButtons.jsx b/src/components/Filters/FilterButtons.jsx index e3dc66c..e7846e9 100644 --- a/src/components/Filters/FilterButtons.jsx +++ b/src/components/Filters/FilterButtons.jsx @@ -1,30 +1,36 @@ import React from "react"; -import "./../../styles/filters.css"; +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" }, + { code: "News", label: "News", icon: "fa-solid fa-newspaper" }, + { code: "Friends", label: "Friends", icon: "fa-solid fa-user-group" }, + { code: "Events", label: "Events", icon: "fa-solid fa-calendar-days" }, + { code: "Market", label: "Market", icon: "fa-solid fa-chart-line" }, + ]; -export default function FilterButtons({ onSelect }) { return ( -
- - - - - - - - - +
+ {buttons.map((btn) => ( + + ))}
); } diff --git a/src/components/Map/MapView.jsx b/src/components/Map/MapView.jsx index e5f0ca2..7ac8479 100644 --- a/src/components/Map/MapView.jsx +++ b/src/components/Map/MapView.jsx @@ -3,6 +3,7 @@ import "maplibre-gl/dist/maplibre-gl.css"; import "../../styles/mapMarkers.css"; import "../../styles/overlays.css"; import "../../styles/posts.css"; +import "../../styles/filters.css"; import { createPost } from "../../api/client"; import { @@ -15,6 +16,7 @@ import { useUserPosition } from "./useUserPosition"; import { usePostsEngine } from "./usePostsEngine"; import PostList from "../Posts/PostList"; import { useAuth } from "../../auth/AuthContext"; +import FilterButtons from "../Filters/FilterButtons"; export default function MapView({ theme = "dark" }) { const { authenticated, username, token } = useAuth(); @@ -93,7 +95,7 @@ export default function MapView({ theme = "dark" }) { handleIncomingPost(msg.post); } } catch { - // ignore + // ignore bad messages } }; return () => ws && ws.close(); @@ -137,7 +139,7 @@ export default function MapView({ theme = "dark" }) { const authorName = (username || "").trim() || "anon"; - // Crosshair offset fix + // Crosshair offset: adjust so big bubble sits correctly above pointer let baseLng; let baseLat; @@ -150,7 +152,8 @@ export default function MapView({ theme = "dark" }) { baseLat = center.lat; } - const pixelOffsetY = -20; + const pixelOffsetY = -20; // tweak if needed + const screenPoint = map.project([baseLng, baseLat]); const correctedPoint = { x: screenPoint.x, @@ -181,6 +184,7 @@ export default function MapView({ theme = "dark" }) { token ); + // Inject directly into the posts engine in addition to WebSocket broadcast if (newPost && newPost.id) { handleIncomingPost(newPost); } @@ -205,12 +209,18 @@ 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); + }; + return (
{status &&
{status}
} - {/* TOP: Look / Place */} + {/* TOP */}
- {/* LEFT: time filters – NOW / TODAY / RECENT / PAST */} -
+ {/* LEFT (time filters) */} +
{[ ["NOW", "Now"], ["TODAY", "Today"], - ["RECENT", "Recent"], + ["RECENT", "Recently"], ["PAST", "Past"], ].map(([code, label]) => ( -
- - {label} -
- ))} -
- - {/* RIGHT: main categories – ALL / NEWS / FRIENDS / EVENTS / MARKET */} -
- {FILTER_MAIN_CATEGORIES.map((cat) => { - const label = cat; - return ( -
- - {label} -
- ); - })} -
- - {/* BOTTOM: subcategories */} -
- {bottomCategories.map((c) => ( ))}
+ {/* RIGHT (main categories with glossy icons) */} +
+ +
+ + {/* BOTTOM (subcategories glossy pills) */} +
+
+ {bottomCategories.map((c) => ( + + ))} +
+
+ {/* MY SPOT */}
- {/* CROSSHAIR */} + {/* CROSSHAIR when creating a post */} {isCreating && (
diff --git a/src/styles/filters.css b/src/styles/filters.css index 9a43e26..97f5382 100644 --- a/src/styles/filters.css +++ b/src/styles/filters.css @@ -1,37 +1,80 @@ +/* ===== SocioWire glossy filter buttons ===== */ + +/* Vertical circular category buttons (right side) */ +.sw-filter-column { + display: flex; + flex-direction: column; + gap: 0.6rem; +} + .sw-filter-btn { - width: 72px; - height: 72px; + width: 70px; + height: 70px; border-radius: 50%; - background: radial-gradient(circle at 30% 30%, #38bdf8, #1d4ed8, #0b1020); - border: 2px solid rgba(255,255,255,0.25); - box-shadow: 0 4px 12px rgba(0,0,0,0.6); + 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); display: flex; flex-direction: column; align-items: center; justify-content: center; - color: #fff; + color: #e5f0ff; cursor: pointer; - transition: transform .15s, box-shadow .15s; -} - -.sw-filter-btn:hover { - transform: translateY(-3px); - box-shadow: 0 6px 20px rgba(0,0,0,0.75); + transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease; } .sw-filter-btn i { - font-size: 26px; - margin-bottom: 4px; + font-size: 24px; + margin-bottom: 2px; } .sw-filter-label { font-size: 0.7rem; - margin-top: 4px; - text-align: center; - color: #dbeafe; + line-height: 1; + 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-filter-active { border-color: #38bdf8; - box-shadow: 0 0 16px #38bdf8; + box-shadow: 0 0 18px rgba(56,189,248,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); +} + +.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; + font-weight: 600; }