Skip to content

Commit d1e768f

Browse files
author
Florian Maas
committed
Welcome banner
1 parent 2c03315 commit d1e768f

4 files changed

Lines changed: 46 additions & 4 deletions

File tree

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { X } from "lucide-react";
2+
import { useGalaxyStore } from "../store/useGalaxyStore";
3+
4+
export function WelcomeBanner() {
5+
const dismissWelcome = useGalaxyStore((s) => s.dismissWelcome);
6+
7+
return (
8+
<div className="bg-gray-900/95 backdrop-blur-md rounded-lg px-4 py-4 sm:px-6 sm:py-4 shadow-2xl w-full sm:w-96 border border-gray-700/50 relative">
9+
<button
10+
onClick={dismissWelcome}
11+
className="absolute top-3 right-3 text-white bg-gray-700 hover:bg-gray-600 transition-colors p-1.5 rounded-full"
12+
aria-label="Dismiss welcome message"
13+
>
14+
<X size={16} />
15+
</button>
16+
17+
<h2 className="text-white text-lg font-bold mb-2 pr-8">
18+
Welcome to PyAtlas
19+
</h2>
20+
21+
<p className="text-gray-300 text-sm leading-relaxed">
22+
Explore 10,000 popular Python packages on an interactive map. Packages
23+
with similar functionality are displayed close together. Click any point
24+
to learn more, or use search to find a specific package.
25+
</p>
26+
</div>
27+
);
28+
}

frontend/src/components/layout/DesktopLayout.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Menu } from "lucide-react";
22
import { Sidebar } from "./Sidebar/Sidebar";
33
import { PackageDetail } from "../PackageDetail";
4+
import { WelcomeBanner } from "../WelcomeBanner";
45
import { SearchBar } from "../SearchBar";
56
import { FloatingGitHubButton } from "../shared/FloatingGitHubButton";
67
import { ZoomControls } from "../shared/ZoomControls";
@@ -33,6 +34,7 @@ function CollapsedTopBar() {
3334

3435
export function DesktopLayout() {
3536
const isSidebarOpen = useGalaxyStore((s) => s.isSidebarOpen);
37+
const welcomeDismissed = useGalaxyStore((s) => s.welcomeDismissed);
3638

3739
return (
3840
<>
@@ -42,12 +44,12 @@ export function DesktopLayout() {
4244
{/* Sidebar */}
4345
<Sidebar />
4446

45-
{/* Package Detail - positioned next to sidebar when open */}
47+
{/* Welcome Banner or Package Detail - positioned next to sidebar when open */}
4648
<div
4749
className={`fixed bottom-6 z-40 pointer-events-auto transition-[left] duration-300 ease-in-out
4850
${isSidebarOpen ? "left-[344px]" : "left-6"}`}
4951
>
50-
<PackageDetail />
52+
{welcomeDismissed ? <PackageDetail /> : <WelcomeBanner />}
5153
</div>
5254

5355
{/* Bottom right controls */}

frontend/src/components/layout/MobileLayout.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
import { TopBar } from "./TopBar";
22
import { PackageDetail } from "../PackageDetail";
3+
import { WelcomeBanner } from "../WelcomeBanner";
34
import { FloatingGitHubButton } from "../shared/FloatingGitHubButton";
45
import { ZoomControls } from "../shared/ZoomControls";
6+
import { useGalaxyStore } from "../../store/useGalaxyStore";
57

68
export function MobileLayout() {
9+
const welcomeDismissed = useGalaxyStore((s) => s.welcomeDismissed);
10+
711
return (
812
<>
913
<TopBar />
@@ -16,7 +20,7 @@ export function MobileLayout() {
1620
<div className="self-end sm:order-2 sm:hidden">
1721
<ZoomControls />
1822
</div>
19-
<PackageDetail />
23+
{welcomeDismissed ? <PackageDetail /> : <WelcomeBanner />}
2024
</div>
2125
</div>
2226

frontend/src/store/useGalaxyStore.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ interface GalaxyStore {
4848
highlightedClusterId: number | null;
4949
highlightStartTime: number | null;
5050
packageDetailExpanded: boolean;
51+
welcomeDismissed: boolean;
5152

5253
setPackages: (packages: Package[]) => void;
5354
setClusters: (clusters: Cluster[]) => void;
@@ -72,6 +73,7 @@ interface GalaxyStore {
7273
setHighlightedCluster: (clusterId: number | null) => void;
7374
focusOnCluster: (clusterId: number) => void;
7475
setPackageDetailExpanded: (expanded: boolean) => void;
76+
dismissWelcome: () => void;
7577
}
7678

7779
export const useGalaxyStore = create<GalaxyStore>((set) => ({
@@ -97,6 +99,7 @@ export const useGalaxyStore = create<GalaxyStore>((set) => ({
9799
highlightedClusterId: null,
98100
highlightStartTime: null,
99101
packageDetailExpanded: true,
102+
welcomeDismissed: false,
100103

101104
setPackages: (packages) => set({ packages }),
102105
setClusters: (clusters) => {
@@ -120,7 +123,11 @@ export const useGalaxyStore = create<GalaxyStore>((set) => ({
120123
}
121124
return { selectedClusterIds: newSet };
122125
}),
123-
setSelectedPackageId: (id) => set({ selectedPackageId: id }),
126+
setSelectedPackageId: (id) =>
127+
set((state) => ({
128+
selectedPackageId: id,
129+
welcomeDismissed: id !== null ? true : state.welcomeDismissed,
130+
})),
124131
setHoveredIndex: (index) => set({ hoveredIndex: index }),
125132
setSearchQuery: (query) => set({ searchQuery: query }),
126133
setSearchResults: (results) => set({ searchResults: results }),
@@ -171,4 +178,5 @@ export const useGalaxyStore = create<GalaxyStore>((set) => ({
171178
}),
172179
setPackageDetailExpanded: (expanded) =>
173180
set({ packageDetailExpanded: expanded }),
181+
dismissWelcome: () => set({ welcomeDismissed: true }),
174182
}));

0 commit comments

Comments
 (0)