From 209249e95980dd0f0e4d92d187cf86d8515b3cd4 Mon Sep 17 00:00:00 2001 From: Brandon Saldan <26472557+brandonsaldan@users.noreply.github.com> Date: Wed, 25 Dec 2024 22:17:38 -0500 Subject: [PATCH] feat(bento): add interactivity to code blocks --- bun.lockb | Bin 169101 -> 169462 bytes package.json | 1 + src/app/page.tsx | 95 +-------------- src/components/left-code-tabs.tsx | 180 +++++++++++++++++++++++++++++ src/components/right-code-tabs.tsx | 172 +++++++++++++++++++++++++++ 5 files changed, 357 insertions(+), 91 deletions(-) create mode 100644 src/components/left-code-tabs.tsx create mode 100644 src/components/right-code-tabs.tsx diff --git a/bun.lockb b/bun.lockb index 895d5db80755912f4263b74221f2c7416eb21499..aa18124c653b449ccb03eccfaed31fbc63482654 100755 GIT binary patch delta 31262 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 delta 31309 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 F{|{n&Rj>d6 diff --git a/package.json b/package.json index b212b70..3ab3afd 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "prismjs": "^1.29.0", "react": "^18", "react-dom": "^18", + "react-icons": "^5.4.0", "react-use-measure": "^2.1.1" }, "devDependencies": { diff --git a/src/app/page.tsx b/src/app/page.tsx index 8670d40..cd1fcbd 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -5,10 +5,12 @@ import { Container } from '@/components/container' import { Footer } from '@/components/footer' import { Gradient } from '@/components/gradient' import { InterstateRows } from '@/components/interstate-rows' +import LeftCodeTabs from '@/components/left-code-tabs' import { Link } from '@/components/link' import { LogoCluster } from '@/components/logo-cluster' import { Map } from '@/components/map' import { Navbar } from '@/components/navbar' +import RightCodeTabs from '@/components/right-code-tabs' import { Testimonials } from '@/components/testimonials' import { Heading, Subheading } from '@/components/text' import { ChevronRightIcon } from '@heroicons/react/16/solid' @@ -75,54 +77,7 @@ function BentoSection() { eyebrow="Free" title="Open Source" description="Built by the community, for the community. Always free and open source." - graphic={ -
-
-
-
-
-
-
- playlistService.jsx -
-
- artistService.jsx -
-
-
-
- { - try { - const response = await fetch("https://api.spotify.com/v1/me/playlists", { - headers: { - Authorization: \`Bearer \${accessToken}\`, - }, - }); - if (response.ok) { - const data = await response.json(); - const validPlaylists = data.items.filter(item => item && item.id); - if (validPlaylists.length > 0) { - const imageUrl = validPlaylists[0].images[0]?.url; - if (imageUrl) { - localStorage.setItem("libraryImage", imageUrl); - updateGradientColors(imageUrl, "library"); - } - } - setPlaylists(validPlaylists); - } else { - console.error("Error fetching user playlists:", response.status); - } - } catch (error) { - console.error("Error fetching user playlists:", error.message); - } -};`} - /> -
-
-
-
- } + graphic={} fade={['bottom']} className="max-lg:rounded-t-4xl lg:col-span-3 lg:rounded-tl-4xl" /> @@ -130,49 +85,7 @@ function BentoSection() { eyebrow="Simple" title="Easy Setup" description="Get up and running in minutes with our step-by-step installation guide and community support." - graphic={ -
-
-
-
-
-
-
- setup_hotspot.py -
-
- README.md -
-
-
-
-                    
-                      If you haven't already, download superbird-tool and run
-                      the setup process detailed here.
-                    
-                    
-                      Download and unzip the latest image from Releases, connect
-                      Car Thing to your computer in USB Mode (hold preset
-                      buttons 1 and 4 while connecting), and run the following
-                      from your command line:
-                    
-                    
-                      # Go into the superbird-tool repository
-                    
-                    
-                      $ cd C:\path\to\superbird-tool-main
-                    
-                    
-                      # Find device
-                    
-                    
-                      $ python superbird_tool.py --find_device
-                    
-                  
-
-
-
- } + graphic={} fade={['bottom']} className="lg:col-span-3 lg:rounded-tr-4xl" /> diff --git a/src/components/left-code-tabs.tsx b/src/components/left-code-tabs.tsx new file mode 100644 index 0000000..f59a373 --- /dev/null +++ b/src/components/left-code-tabs.tsx @@ -0,0 +1,180 @@ +import dynamic from 'next/dynamic' +import { useEffect, useState } from 'react' +import { FaJsSquare, FaReact } from 'react-icons/fa' + +const CodeBlock = dynamic(() => import('@/components/code-block'), { + ssr: false, +}) + +type TabKey = 'playlist' | 'artist' + +interface TabContent { + title: string + code: string +} + +interface TabsData { + playlist: TabContent + artist: TabContent +} + +const LeftCodeTabs = () => { + const [activeTab, setActiveTab] = useState('playlist') + const [isMounted, setIsMounted] = useState(false) + const [isChanging, setIsChanging] = useState(false) + + useEffect(() => { + setIsMounted(true) + }, []) + + const handleTabChange = (newTab: TabKey) => { + if (newTab === activeTab) return + + setIsChanging(true) + setTimeout(() => { + setActiveTab(newTab) + setIsChanging(false) + }, 150) + } + + const tabs: TabsData = { + playlist: { + title: 'playlistService.js', + code: `export const fetchUserPlaylists = async ( + accessToken, + setPlaylists, + updateGradientColors, + handleError +) => { + try { + const response = await fetch("https://api.spotify.com/v1/me/playlists", { + headers: { + Authorization: \`Bearer \${accessToken}\`, + }, + }); + if (response.ok) { + const data = await response.json(); + const validPlaylists = data.items.filter((item) => item && item.id); + if (validPlaylists.length > 0) { + const imageUrl = validPlaylists[0].images?.[0]?.url; + if (imageUrl) { + localStorage.setItem("libraryImage", imageUrl); + updateGradientColors(imageUrl, "library"); + } + } + setPlaylists(validPlaylists); + } else { + console.error("Error fetching user playlists:", response.status); + } + } catch (error) { + console.error("Error fetching user playlists:", error.message); + } +};`, + }, + artist: { + title: 'AuthSelection.jsx', + code: `const enableBluetoothDiscovery = async () => { + try { + setIsBluetoothDiscovering(true); + const response = await fetch( + "http://localhost:5000/bluetooth/discover/on", + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + } + ); + + if (!response.ok) { + throw new Error("Failed to enable bluetooth discovery"); + } + + setTimeout(() => { + setIsBluetoothDiscovering(false); + fetch("http://localhost:5000/bluetooth/discover/off", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + }).catch(console.error); + }, 120000); + } catch (error) { + console.error("Error enabling bluetooth discovery:", error); + setIsBluetoothDiscovering(false); + } +};`, + }, + } + + return ( +
+
+
+
+
+
+
handleTabChange('playlist')} + className="relative cursor-pointer" + > +
+
+ + {tabs.playlist.title} +
+
+
+
+
handleTabChange('artist')} + className="relative cursor-pointer" + > +
+
+ + {tabs.artist.title} +
+
+
+
+
+
+
+ {isMounted && ( +
+ +
+ )} +
+
+
+
+ ) +} + +export default LeftCodeTabs diff --git a/src/components/right-code-tabs.tsx b/src/components/right-code-tabs.tsx new file mode 100644 index 0000000..4abdb6f --- /dev/null +++ b/src/components/right-code-tabs.tsx @@ -0,0 +1,172 @@ +import dynamic from 'next/dynamic' +import { useEffect, useState } from 'react' +import { FaPython } from 'react-icons/fa' +import { RiMarkdownFill } from 'react-icons/ri' + +const CodeBlock = dynamic(() => import('@/components/code-block'), { + ssr: false, +}) + +type TabKey = 'setup' | 'readme' + +interface TabContent { + title: string + code: string +} + +interface TabsData { + setup: TabContent + readme: TabContent +} + +const RightCodeTabs = () => { + const [activeTab, setActiveTab] = useState('readme') + const [isMounted, setIsMounted] = useState(false) + const [isChanging, setIsChanging] = useState(false) + + useEffect(() => { + setIsMounted(true) + }, []) + + const handleTabChange = (newTab: TabKey) => { + if (newTab === activeTab) return + + setIsChanging(true) + setTimeout(() => { + setActiveTab(newTab) + setIsChanging(false) + }, 150) + } + + const tabs: TabsData = { + setup: { + title: 'setup_hotspot.py', + code: `def setup_hotspot(): + # Check if WiFi is available + wifi_status = check_wifi_status() + if not wifi_status: + print("Error: WiFi hardware not detected") + return False + + # Create hotspot configuration + config = { + "ssid": "Car_Thing_Setup", + "wpa_passphrase": generate_password(), + "ip_range": "192.168.4.0/24" + } + + # Apply configuration + success = apply_hotspot_config(config) + if not success: + print("Error: Failed to configure hotspot") + return False + + # Start hotspot service + if start_hotspot_service(): + print("Hotspot started successfully") + print(f"SSID: {config['ssid']}") + print(f"Password: {config['wpa_passphrase']}") + return True + else: + print("Error: Failed to start hotspot") + return False`, + }, + readme: { + title: 'README.md', + code: `# Car Thing Setup Guide + +1. Download superbird-tool and run the setup process detailed here. + +2. Download and unzip the latest image from Releases. + +3. Connect Car Thing to your computer in USB Mode: + - Hold preset buttons 1 and 4 while connecting + - Wait for device recognition + +4. Open your command line and run: + + # Go into the superbird-tool repository + $ cd C:\\path\\to\\superbird-tool-main + + # Find device + $ python superbird_tool.py --find_device + + # Flash the new image + $ python superbird_tool.py --flash path/to/nocturne.img + +5. Wait for the process to complete. + Do not disconnect the device during flashing.`, + }, + } + + return ( +
+
+
+
+
+
+
handleTabChange('setup')} + className="relative cursor-pointer" + > +
+
+ + {tabs.setup.title} +
+
+
+
+
handleTabChange('readme')} + className="relative cursor-pointer" + > +
+
+ + {tabs.readme.title} +
+
+
+
+
+
+
+ {isMounted && ( +
+ +
+ )} +
+
+
+
+ ) +} + +export default RightCodeTabs