Skip to content

Commit fee148f

Browse files
authored
πŸ₯‚πŸ‘·β€β™‚οΈ ↝ [SSG-286 SSF-42]: Merge pull request #206 from Signal-K/SSG-286
🧺πŸ₯‚ ↝ [SSG-286 SSF-42]: Secondary missions & tool expansions
2 parents 524f476 + 39423e6 commit fee148f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+4192
-575
lines changed

β€Ž.github/workflows/notify-unclassified-discoveries.ymlβ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,4 @@ jobs:
3434
NEXT_PUBLIC_VAPID_PUBLIC_KEY: ${{ secrets.VAPID_PUBLIC_KEY }}
3535
VAPID_PRIVATE_KEY: ${{ secrets.VAPID_PRIVATE_KEY }}
3636
SUPABASE_DB_URL: ${{ secrets.SUPABASE_DB_URL }}
37-
run: node scripts/notify-unclassified-discoveries.js
37+
run: node scripts/notify-unclassified-discoveries.js

β€Žapp/RootLayoutClient.tsxβ€Ž

Whitespace-only changes.

β€Žapp/activity-layout.tsxβ€Ž

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
"use client";
2+
3+
import { useEffect, useState, ReactNode } from "react";
4+
import { createPagesBrowserClient } from "@supabase/auth-helpers-nextjs";
5+
import { SessionContextProvider } from "@supabase/auth-helpers-react";
6+
import { ActivePlanetProvider } from "@/src/core/context/ActivePlanet";
7+
import { UserAnomaliesProvider } from "@/src/core/context/UserAnomalies";
8+
import Sidebar from "@/src/components/ui/Panels/Sidebar";
9+
import { Analytics } from "@vercel/analytics/react";
10+
import { SpeedInsights } from "@vercel/speed-insights/next";
11+
12+
export default function ActivityLayout({ children }: { children: ReactNode }) {
13+
const [supabaseClient] = useState(() => createPagesBrowserClient());
14+
const [session, setSession] = useState<any>(null);
15+
const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
16+
17+
useEffect(() => {
18+
supabaseClient.auth.getSession().then(({ data }) => {
19+
setSession(data?.session ?? null);
20+
});
21+
// Listen for sidebar collapse/expand events
22+
const handler = (e: CustomEvent) => {
23+
setSidebarCollapsed(e.detail.collapsed);
24+
};
25+
window.addEventListener("sidebar:collapse", handler as EventListener);
26+
return () => {
27+
window.removeEventListener("sidebar:collapse", handler as EventListener);
28+
};
29+
}, [supabaseClient]);
30+
31+
return (
32+
<html lang="en">
33+
<body>
34+
<SessionContextProvider supabaseClient={supabaseClient} initialSession={null}>
35+
<ActivePlanetProvider>
36+
<UserAnomaliesProvider>
37+
<div className="flex min-h-screen w-full">
38+
{/* Sidebar: fixed to left, does not scroll, desktop only */}
39+
{session && (
40+
<div className="hidden sm:block fixed left-0 top-0 h-screen z-40">
41+
<Sidebar />
42+
</div>
43+
)}
44+
{/* Main content: margin-left for sidebar width, center if sidebar is collapsed, no margin if sidebar hidden */}
45+
<main
46+
className={
47+
session
48+
? (sidebarCollapsed
49+
? "flex-1 min-w-0 ml-16 flex justify-center items-center"
50+
: "flex-1 min-w-0 ml-16 md:ml-80")
51+
: "flex-1 min-w-0"
52+
}
53+
>
54+
{children}
55+
</main>
56+
</div>
57+
<Analytics />
58+
<SpeedInsights />
59+
</UserAnomaliesProvider>
60+
</ActivePlanetProvider>
61+
</SessionContextProvider>
62+
</body>
63+
</html>
64+
);
65+
}

β€Žapp/activity/deploy/page.tsxβ€Ž

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { ArrowLeft, User, Sun, Moon } from "lucide-react"
1010
import { useEffect, useState } from "react"
1111
import { Switch } from "@/src/components/ui/switch"
1212
import UseDarkMode from "@/src/shared/hooks/useDarkMode"
13+
import GameNavbar from "@/src/components/layout/Tes"
1314

1415
export default function NewDeployPage() {
1516
const router = useRouter()
@@ -47,6 +48,7 @@ export default function NewDeployPage() {
4748

4849
return (
4950
<div className="h-screen w-full flex flex-col bg-gradient-to-b from-[#002439] to-[#001a2a] overflow-hidden">
51+
<GameNavbar />
5052
<DeployTelescopeViewport />
5153
</div>
5254
);
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
"use client";
2+
3+
import React, { useEffect, useState } from "react";
4+
import { useSupabaseClient, useSession } from "@supabase/auth-helpers-react";
5+
import MainHeader from "@/src/components/layout/Header/MainHeader";
6+
import UseDarkMode from "@/src/shared/hooks/useDarkMode";
7+
import { usePageData, useGroupedClassifications } from "@/hooks/usePageData";
8+
import { ClassificationTypeIcon } from "@/src/components/classification/ClassificationTypeIcon";
9+
import { AnnotationOptionLabel } from "@/src/components/classification/AnnotationOptionLabel";
10+
import ActivityHeaderSection from "@/src/components/social/activity/ActivityHeaderSection";
11+
import Login from "@/app/auth/page";
12+
13+
export default function UserClassificationsInventoryPage() {
14+
const session = useSession();
15+
16+
const [notificationsOpen, setNotificationsOpen] = useState(false);
17+
const [landmarksExpanded, setLandmarksExpanded] = useState(false);
18+
const [showTipsPanel, setShowTipsPanel] = useState(false);
19+
const [showProfileModal, setShowProfileModal] = useState(false);
20+
const { isDark, toggleDarkMode } = UseDarkMode();
21+
22+
const {
23+
linkedAnomalies,
24+
activityFeed,
25+
profile,
26+
classifications,
27+
otherClassifications,
28+
incompletePlanet,
29+
planetTargets,
30+
visibleStructures,
31+
loading,
32+
} = usePageData();
33+
34+
// Debug: log all classificationConfiguration objects
35+
useEffect(() => {
36+
if (classifications && classifications.length > 0) {
37+
console.log("classificationConfigurations:", classifications.map(c => c.classificationConfiguration));
38+
}
39+
}, [classifications]);
40+
41+
// Debug: log all classificationConfiguration objects
42+
useEffect(() => {
43+
if (classifications && classifications.length > 0) {
44+
console.log("classificationConfigurations:", classifications.map(c => c.classificationConfiguration));
45+
}
46+
}, [classifications]);
47+
48+
// Patch: ensure annotationOptions are extracted from classificationConfiguration
49+
const patchedClassifications = classifications.map((c) => {
50+
let annotationOptions: string[] = [];
51+
if (c.classificationConfiguration && typeof c.classificationConfiguration === "object") {
52+
if (Array.isArray(c.classificationConfiguration.annotationOptions)) {
53+
annotationOptions = c.classificationConfiguration.annotationOptions as string[];
54+
}
55+
}
56+
return { ...c, annotationOptions };
57+
});
58+
const grouped = useGroupedClassifications(patchedClassifications);
59+
60+
if (!session) {
61+
return (
62+
<Login />
63+
);
64+
};
65+
66+
return (
67+
<div className={`min-h-screen w-full relative flex justify-center ${isDark ? "text-[#E5EEF4]" : "text-[#232a36]"}`}>
68+
{/* Telescope Background - Full screen behind everything */}
69+
<div className="fixed inset-0 -z-10">
70+
{/* You can use a similar background as research, or a themed one for inventory */}
71+
<div className={isDark ? "bg-gradient-to-br from-[#232a36] via-[#1e293b] to-[#0f172a] w-full h-full" : "bg-gradient-to-br from-[#E5EEF4] via-[#D8E5EC] to-[#BFD7EA] w-full h-full"} />
72+
</div>
73+
{/* Main Header */}
74+
<MainHeader
75+
isDark={isDark}
76+
onThemeToggle={toggleDarkMode}
77+
notificationsOpen={notificationsOpen}
78+
onToggleNotifications={() => setNotificationsOpen((open) => !open)}
79+
activityFeed={activityFeed}
80+
otherClassifications={otherClassifications}
81+
/>
82+
{/* Main content with more space from sidebar and reduced width */}
83+
<div className="w-full flex justify-center pt-24 relative z-10">
84+
<div className="w-full max-w-3xl px-6 md:px-8 lg:px-12 xl:px-0">
85+
{/* Activity Header from main page */}
86+
<div className="mb-10">
87+
{/* Use the same ActivityHeaderSection as research page */}
88+
{/* You may need to import ActivityHeaderSection if not already */}
89+
<ActivityHeaderSection
90+
classificationsCount={classifications.length}
91+
landmarksExpanded={landmarksExpanded}
92+
onToggleLandmarks={() => setLandmarksExpanded((prev) => !prev)}
93+
/>
94+
</div>
95+
<main className="w-full flex flex-col gap-0">
96+
<div className="w-full flex flex-col gap-0">
97+
<h2 className="text-2xl font-bold mb-6 text-[#81A1C1]">Your Classifications</h2>
98+
{loading ? (
99+
<div className="text-center py-8 text-muted-foreground">Loading...</div>
100+
) : grouped.length === 0 ? (
101+
<div className="text-center py-8 text-muted-foreground">No classifications found.</div>
102+
) : (
103+
<div className="space-y-8">
104+
{grouped.map(({ type, entries }) => (
105+
<div key={type} className="rounded-3xl shadow-xl py-8 px-6 mb-6" style={{background: isDark ? "rgba(35,42,54,0.85)" : "rgba(229,238,244,0.85)"}}>
106+
<div className="flex items-center gap-2 mb-4">
107+
<ClassificationTypeIcon type={type} className="w-7 h-7" />
108+
<span className="text-lg font-semibold capitalize text-[#81A1C1]">{type}</span>
109+
<span className="ml-2 text-xs text-muted-foreground">{entries.length} entries</span>
110+
</div>
111+
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
112+
{entries.map((c) => (
113+
<div key={c.id} className="rounded-xl p-5 bg-white/80 dark:bg-[#2E3440]/80 shadow flex flex-col gap-2 border border-[#5E81AC]/30">
114+
<div className="flex items-center gap-2">
115+
<ClassificationTypeIcon type={type} className="w-5 h-5" />
116+
<span className="font-mono text-sm text-primary">ID: {c.id}</span>
117+
<span className="text-xs text-muted-foreground ml-auto">{new Date(c.created_at).toLocaleString()}</span>
118+
</div>
119+
<div className="text-sm text-foreground mb-1">{c.content || <span className="italic text-muted-foreground">No content</span>}</div>
120+
<div className="flex flex-wrap gap-1">
121+
{c.annotationOptions && c.annotationOptions.length > 0 ? (
122+
c.annotationOptions.map((opt, i) => (
123+
<AnnotationOptionLabel key={i} option={opt} />
124+
))
125+
) : (
126+
<span className="text-xs text-muted-foreground">No annotation options</span>
127+
)}
128+
</div>
129+
<div className="flex gap-2 mt-2">
130+
<a
131+
href={`/posts/${c.id}`}
132+
className="px-3 py-1 rounded bg-primary text-white text-xs font-mono hover:bg-primary/80 transition"
133+
>
134+
View
135+
</a>
136+
<button
137+
className="px-3 py-1 rounded bg-muted text-foreground text-xs font-mono border border-border hover:bg-muted/80 transition"
138+
type="button"
139+
>
140+
Inspect
141+
</button>
142+
{type === "planet" && (
143+
<a
144+
href={`/planets/paint/${c.id}`}
145+
className="px-3 py-1 rounded bg-[#81A1C1] text-white text-xs font-mono hover:bg-[#5E81AC] transition"
146+
>
147+
Paint
148+
</a>
149+
)}
150+
</div>
151+
</div>
152+
))}
153+
</div>
154+
</div>
155+
))}
156+
</div>
157+
)}
158+
</div>
159+
</main>
160+
</div>
161+
</div>
162+
</div>
163+
);
164+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
"use client";
2+
3+
import { useEffect, useState, ReactNode } from "react";
4+
import { createPagesBrowserClient } from "@supabase/auth-helpers-nextjs";
5+
import { SessionContextProvider } from "@supabase/auth-helpers-react";
6+
import { ActivePlanetProvider } from "@/src/core/context/ActivePlanet";
7+
import { UserAnomaliesProvider } from "@/src/core/context/UserAnomalies";
8+
import Sidebar from "@/src/components/ui/Panels/Sidebar";
9+
import { Analytics } from "@vercel/analytics/react";
10+
import { SpeedInsights } from "@vercel/speed-insights/next";
11+
12+
export default function ActivityLayout({ children }: { children: ReactNode }) {
13+
const [supabaseClient] = useState(() => createPagesBrowserClient());
14+
const [session, setSession] = useState<any>(null);
15+
const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
16+
17+
useEffect(() => {
18+
supabaseClient.auth.getSession().then(({ data }) => {
19+
setSession(data?.session ?? null);
20+
});
21+
// Listen for sidebar collapse/expand events
22+
const handler = (e: CustomEvent) => {
23+
setSidebarCollapsed(e.detail.collapsed);
24+
};
25+
window.addEventListener("sidebar:collapse", handler as EventListener);
26+
return () => {
27+
window.removeEventListener("sidebar:collapse", handler as EventListener);
28+
};
29+
}, [supabaseClient]);
30+
31+
return (
32+
<html lang="en">
33+
<body>
34+
<SessionContextProvider supabaseClient={supabaseClient} initialSession={null}>
35+
<ActivePlanetProvider>
36+
<UserAnomaliesProvider>
37+
<div className="flex min-h-screen w-full">
38+
{/* Sidebar: fixed to left, does not scroll, desktop only */}
39+
{session && (
40+
<div className="hidden sm:block fixed left-0 top-0 h-screen z-40">
41+
<Sidebar />
42+
</div>
43+
)}
44+
{/* Main content: margin-left for sidebar width, center if sidebar is collapsed, no margin if sidebar hidden */}
45+
<main
46+
className={
47+
session
48+
? (sidebarCollapsed
49+
? "flex-1 min-w-0 ml-16 flex justify-center items-center"
50+
: "flex-1 min-w-0 ml-16 md:ml-80")
51+
: "flex-1 min-w-0"
52+
}
53+
>
54+
{children}
55+
</main>
56+
</div>
57+
<Analytics />
58+
<SpeedInsights />
59+
</UserAnomaliesProvider>
60+
</ActivePlanetProvider>
61+
</SessionContextProvider>
62+
</body>
63+
</html>
64+
);
65+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
"use client";
2+
3+
import ActivityLayout from "./activity-layout";
4+
import { ReactNode } from "react";
5+
6+
export default function Layout({ children }: { children: ReactNode }) {
7+
return <ActivityLayout>{children}</ActivityLayout>;
8+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default } from "../../page";

β€Žapp/page.tsxβ€Ž

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import { usePageData } from "@/hooks/usePageData";
3636
import { useSatelliteManagement } from "@/hooks/useSatelliteManagement";
3737
import { useNPSManagement } from "@/hooks/useNPSManagement";
3838
import UseDarkMode from "@/src/shared/hooks/useDarkMode";
39-
import SatellitePosition from "@/src/components/ui/scenes/deploy/SatellitePosition";
39+
import SatellitePosition from "@/src/components/ui/scenes/deploy/satellite/SatellitePosition";
4040
import SolarHealth from "@/src/components/ui/scenes/deploy/solar/SolarHealth";
4141
import TelescopeViewportSection from "@/src/components/ui/scenes/deploy/Telescope/TelescopeSection";
4242
import RoverViewportSection from "@/src/components/ui/scenes/deploy/Rover/RoverSection";
@@ -78,12 +78,6 @@ export default function ActivityPage() {
7878
loading,
7979
} = usePageData();
8080

81-
const {
82-
activeSatelliteMessage,
83-
handleSendSatellite,
84-
checkActiveSatellite,
85-
} = useSatelliteManagement();
86-
8781
const { showNpsModal, handleCloseNps } = useNPSManagement();
8882

8983
// Use the global theme hook

β€Žapp/planets/paint/[id]/page.tsxβ€Ž

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,20 @@ export default function PlanetGeneratorPage() {
8181
fetchPlanetData()
8282
}, [planetId, supabase])
8383

84+
// Hide sidebar for this page
85+
useEffect(() => {
86+
if (typeof window !== "undefined") {
87+
window.dispatchEvent(new CustomEvent("sidebar:collapse", { detail: { collapsed: true } }));
88+
window.localStorage.setItem("hideSidebar", "true");
89+
}
90+
return () => {
91+
if (typeof window !== "undefined") {
92+
window.localStorage.removeItem("hideSidebar");
93+
window.dispatchEvent(new CustomEvent("sidebar:collapse", { detail: { collapsed: false } }));
94+
}
95+
};
96+
}, []);
97+
8498
if (loading) {
8599
return (
86100
<div className="w-full h-screen flex items-center justify-center bg-black text-white">
@@ -135,7 +149,7 @@ export default function PlanetGeneratorPage() {
135149
<Button variant="outline" onClick={() => router.push(`/structures/telescope`)}>
136150
🧬 Back to Telescope
137151
</Button>
138-
<Button variant="ghost" onClick={() => router.push("/")}>
152+
<Button variant="ghost" onClick={() => router.push("/")}>
139153
🏠 Home
140154
</Button>
141155
</div>

0 commit comments

Comments
Β (0)