feat: Move world nav buttons into search bars

- Remove top world nav bar
- Add Islands/Planets buttons to Map search bar
- Add Map/Planets buttons to Islands search bar
- Add Map/Islands buttons to Planets search bar
- Move search bars to fixed position just below topbar
- Compact button styling matching map design
- v0.0.107

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Your Name 2026-01-24 20:12:43 +00:00
parent 9706d673c3
commit ef075ccb9b
9 changed files with 113 additions and 50 deletions

4
package-lock.json generated
View File

@ -1,12 +1,12 @@
{
"name": "sociowire-frontend",
"version": "0.0.104",
"version": "0.0.107",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "sociowire-frontend",
"version": "0.0.104",
"version": "0.0.107",
"dependencies": {
"@fortawesome/fontawesome-free": "^7.1.0",
"axios": "^1.13.2",

View File

@ -1,7 +1,7 @@
{
"name": "sociowire-frontend",
"private": true,
"version": "0.0.104",
"version": "0.0.107",
"type": "module",
"scripts": {
"dev": "vite --host 0.0.0.0",

View File

@ -214,31 +214,6 @@ export default function App() {
currentView={currentView}
/>
{/* World Switcher Navigation */}
<div className="world-nav">
<button
className={`world-nav-btn ${currentView === 'map' ? 'is-active' : ''}`}
onClick={handleOpenMap}
>
<i className="fa-solid fa-earth-americas" />
<span>{t('worlds.map')}</span>
</button>
<button
className={`world-nav-btn ${currentView === 'islands' ? 'is-active' : ''}`}
onClick={handleOpenIslands}
>
<i className="fa-solid fa-umbrella-beach" />
<span>{t('worlds.islands')}</span>
</button>
<button
className={`world-nav-btn ${currentView === 'planets' ? 'is-active' : ''}`}
onClick={handleOpenPlanets}
>
<i className="fa-solid fa-globe" />
<span>{t('worlds.planets')}</span>
</button>
</div>
<div className="main-shell">
<AnimatePresence mode="wait">
{/* MAP WORLD - Reality */}
@ -262,6 +237,7 @@ export default function App() {
selectedIsland={selectedIsland}
onSelectIsland={setSelectedIsland}
onOpenIslands={handleOpenIslands}
onOpenPlanets={handleOpenPlanets}
/>
</Suspense>
</div>
@ -308,6 +284,7 @@ export default function App() {
theme={theme}
onIslandClick={handleIslandClick}
onOpenMap={handleOpenMap}
onOpenPlanets={handleOpenPlanets}
/>
</Suspense>
</motion.div>
@ -327,6 +304,7 @@ export default function App() {
<PlanetsWorld
theme={theme}
onOpenMap={handleOpenMap}
onOpenIslands={handleOpenIslands}
/>
</Suspense>
</motion.div>

View File

@ -142,6 +142,7 @@ export default function MapView({
selectedIsland,
onSelectIsland,
onOpenIslands,
onOpenPlanets,
}) {
const { authenticated, username, token, needsEmailVerification } = useAuth();
const CLUSTERS_ENABLED = false;
@ -2238,11 +2239,19 @@ export default function MapView({
<button
type="button"
className="sw-search__iconBtn"
title="Profile Island"
title="Islands"
onClick={() => onOpenIslands && onOpenIslands()}
>
<i className="fa-solid fa-umbrella-beach"></i>
</button>
<button
type="button"
className="sw-search__iconBtn"
title="Planets"
onClick={() => onOpenPlanets && onOpenPlanets()}
>
<i className="fa-solid fa-globe"></i>
</button>
</div>
</div>
</div>

View File

@ -2,7 +2,9 @@
.islands-world {
position: relative;
width: 100%;
min-height: 100vh;
min-height: calc(100vh - 100px);
margin: 0;
padding: 0;
background: linear-gradient(180deg, #0a1628 0%, #0d2847 50%, #1e3a5f 100%);
overflow: hidden;
}
@ -16,21 +18,21 @@
/* Search bar */
.islands-world-search {
position: absolute;
top: 16px;
position: fixed;
top: 56px;
left: 50%;
transform: translateX(-50%);
z-index: 100;
display: flex;
align-items: center;
gap: 10px;
background: rgba(15, 23, 42, 0.9);
gap: 8px;
background: rgba(15, 23, 42, 0.95);
backdrop-filter: blur(20px);
border: 1px solid rgba(56, 189, 248, 0.3);
border-radius: 50px;
padding: 10px 16px;
width: 90%;
max-width: 360px;
padding: 8px 12px;
width: auto;
max-width: 500px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
}
@ -53,6 +55,32 @@
border-radius: 20px;
}
.islands-world-search .world-nav-inline {
display: flex;
gap: 4px;
margin-left: 6px;
}
.islands-world-search .world-nav-btn-sm {
width: 30px;
height: 30px;
border: none;
border-radius: 50%;
background: rgba(255, 255, 255, 0.1);
color: rgba(255, 255, 255, 0.7);
font-size: 13px;
cursor: pointer;
transition: all 0.2s ease;
display: flex;
align-items: center;
justify-content: center;
}
.islands-world-search .world-nav-btn-sm:hover {
background: rgba(56, 189, 248, 0.3);
color: white;
}
.islands-world-search input {
flex: 1;
background: transparent;

View File

@ -10,7 +10,7 @@ import './IslandsWorld.css';
* IslandsWorld: Full-screen metaverse for personal islands
* Each user has their own floating island in this virtual ocean
*/
export default function IslandsWorld({ theme, onIslandClick, onOpenMap }) {
export default function IslandsWorld({ theme, onIslandClick, onOpenMap, onOpenPlanets }) {
const { t } = useTranslation();
const { authenticated, username } = useAuth();
const containerRef = useRef(null);
@ -180,7 +180,7 @@ export default function IslandsWorld({ theme, onIslandClick, onOpenMap }) {
return (
<div className="islands-world">
{/* Search bar with icon */}
{/* Search bar with icon and world nav */}
<div className="islands-world-search">
<i className="fa-solid fa-umbrella-beach search-icon" />
<i className="fa-solid fa-search" />
@ -196,6 +196,14 @@ export default function IslandsWorld({ theme, onIslandClick, onOpenMap }) {
</button>
)}
<span className="search-count">{islands.length}</span>
<div className="world-nav-inline">
<button className="world-nav-btn-sm" onClick={onOpenMap} title={t('worlds.map')}>
<i className="fa-solid fa-earth-americas" />
</button>
<button className="world-nav-btn-sm" onClick={onOpenPlanets} title={t('worlds.planets')}>
<i className="fa-solid fa-globe" />
</button>
</div>
</div>
{/* Main canvas */}

View File

@ -2,7 +2,9 @@
.planets-world {
position: relative;
width: 100%;
min-height: 100vh;
min-height: calc(100vh - 100px);
margin: 0;
padding: 0;
background: radial-gradient(ellipse at center, #0f0f1a 0%, #050510 70%, #000005 100%);
overflow: hidden;
}
@ -16,21 +18,21 @@
/* Search bar */
.planets-world-search {
position: absolute;
top: 16px;
position: fixed;
top: 56px;
left: 50%;
transform: translateX(-50%);
z-index: 100;
display: flex;
align-items: center;
gap: 10px;
background: rgba(15, 15, 26, 0.9);
gap: 8px;
background: rgba(15, 15, 26, 0.95);
backdrop-filter: blur(20px);
border: 1px solid rgba(155, 89, 182, 0.3);
border-radius: 50px;
padding: 10px 16px;
width: 90%;
max-width: 360px;
padding: 8px 12px;
width: auto;
max-width: 500px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.6);
}
@ -53,6 +55,32 @@
border-radius: 20px;
}
.planets-world-search .world-nav-inline {
display: flex;
gap: 4px;
margin-left: 6px;
}
.planets-world-search .world-nav-btn-sm {
width: 30px;
height: 30px;
border: none;
border-radius: 50%;
background: rgba(255, 255, 255, 0.1);
color: rgba(255, 255, 255, 0.7);
font-size: 13px;
cursor: pointer;
transition: all 0.2s ease;
display: flex;
align-items: center;
justify-content: center;
}
.planets-world-search .world-nav-btn-sm:hover {
background: rgba(155, 89, 182, 0.3);
color: white;
}
.planets-world-search input {
flex: 1;
background: transparent;

View File

@ -10,7 +10,7 @@ import './PlanetsWorld.css';
* PlanetsWorld: Full-screen metaverse for group spaces (planets)
* Each planet represents a community/group floating in space
*/
export default function PlanetsWorld({ theme, onOpenMap }) {
export default function PlanetsWorld({ theme, onOpenMap, onOpenIslands }) {
const { t } = useTranslation();
const { authenticated } = useAuth();
const containerRef = useRef(null);
@ -168,7 +168,7 @@ export default function PlanetsWorld({ theme, onOpenMap }) {
return (
<div className="planets-world">
{/* Search bar with icon */}
{/* Search bar with icon and world nav */}
<div className="planets-world-search">
<i className="fa-solid fa-globe search-icon" />
<i className="fa-solid fa-search" />
@ -184,6 +184,14 @@ export default function PlanetsWorld({ theme, onOpenMap }) {
</button>
)}
<span className="search-count">{planets.length}</span>
<div className="world-nav-inline">
<button className="world-nav-btn-sm" onClick={onOpenMap} title={t('worlds.map')}>
<i className="fa-solid fa-earth-americas" />
</button>
<button className="world-nav-btn-sm" onClick={onOpenIslands} title={t('worlds.islands')}>
<i className="fa-solid fa-umbrella-beach" />
</button>
</div>
</div>
{/* Main canvas */}

View File

@ -210,10 +210,14 @@
/* World containers */
.world-container {
width: 100%;
margin: 0;
padding: 0;
}
.world-fullscreen {
min-height: calc(100vh - 110px);
min-height: calc(100vh - 100px);
margin: 0;
padding: 0;
}
/* World placeholder */