- Expand AI system prompt with full feature map: Lab (coaches/filmers/ photographers/editors/builders + individual vs collective), Crews (map-anchored, how they differ from the Lab), Stash, Tours, Shops, Gear Swap, Rider Card - Document money layer interconnections: wallet rails (Cashu/NWC/WebLN), zap fallback order, nutzaps (NIP-61, receiving), CLINK/noffer, Geyser supporters - Instruct Sasquatch that Crews/Stash/Wallet/Tours/Shops have no live search tool and must be answered from knowledge (prevents bogus tool calls) - Add ~15 new STATIC_FAQ offline answers (crews, stash, builder, nutzap, clink, noffer, tours, shops, sell gear, supporters) - Add Crews page guide context + crew jokes; refresh Lab suggestions - Fix leftover "Zapped with Engorile!" default comment → SkateSpots branding Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
211 lines
9.1 KiB
TypeScript
211 lines
9.1 KiB
TypeScript
import { useState, useEffect } from 'react';
|
|
import { useLocation } from 'react-router-dom';
|
|
import { useCurrentUser } from '@/hooks/useCurrentUser';
|
|
import type { GuideMessage } from '@/components/SasquatchGuide';
|
|
|
|
// Sasquatch's skate jokes - randomly displayed in The Lab
|
|
const LAB_JOKES = [
|
|
"Why did the skateboarder bring a ladder to The Lab? Because they heard the kickflips were on another level! 🛹😂",
|
|
"What do you call a sasquatch who can tre flip? A myth! But seriously, these coaches can teach you anything. 🦧",
|
|
"How do skaters stay cool in summer? They hang out in The Lab where the tricks are always fresh! ❄️",
|
|
"Why don't sasquatches need coaches? Because we're naturally board! But you humans should check out these pros. 🎓",
|
|
"What's a skateboarder's favorite type of music? BOARD rock! Get it? ...I'll see myself out. 🎸",
|
|
"Why did the skateboard go to therapy? It had too many issues with commitment... to grinds! 😅",
|
|
"I tried to teach a tree to skateboard once. It was great until it got board. Now it just stands there. 🌲",
|
|
"What's the difference between a bad skater and a pizza? A pizza can feed a family of four. But these coaches can fix that! 🍕",
|
|
"Why did the skater bring a camera to The Lab? To capture all the moments before they bail! 📸",
|
|
"How many skaters does it take to change a lightbulb? None - they're too busy trying to ollie over it! 💡"
|
|
];
|
|
|
|
// Map and spots jokes - mixed with skateboarding humor
|
|
const MAP_JOKES = [
|
|
"Why did the skate spot go to the doctor? It had too many cracks! 😂 But seriously, report those conditions!",
|
|
"What do you call a sasquatch who knows every spot? A legend! And now you can be one too by adding spots to the map! 🗺️",
|
|
"Why did the skater bring a map to the skatepark? They heard the lines were off the charts! 📍",
|
|
"How do skate shops stay in business? They keep their inventory wheel-y organized! 🛒",
|
|
"What's a spot's favorite season? FALL... get it? Because that's when most people... nevermind. 🍂",
|
|
"Why don't spots ever get lonely? Because skaters always drop in! 😎",
|
|
"I once found a spot so perfect, I thought I was dreaming. Turned out I was just board. 💤",
|
|
"What do skate shops and sasquatches have in common? We both know where the best grip is! 🦧",
|
|
"Why did the ledge break up with the handrail? Too much grinding in the relationship! 💔",
|
|
"How do you make a skate spot laugh? Tell it a crack joke! The spot will split up! 🤣",
|
|
"What's a skater's favorite type of store? One with good boards, of course! And you can find them all here. 🛹",
|
|
"Why do sasquatches love maps? Because X marks the spot... and we ALWAYS find it! ❌"
|
|
];
|
|
|
|
// Crew jokes — for the Crews page
|
|
const CREW_JOKES = [
|
|
"Why did the crew skate together? Because a board shared is a board doubled! 🤘",
|
|
"What do you call a sasquatch's skate crew? The Bigfoot Brigade — we leave big tracks! 🦧",
|
|
"A crew is like grip tape — sticks together and keeps everyone from slipping. 🛹",
|
|
"Why did the crew claim a home spot? So the locals always know where to drop in! 📍",
|
|
"What's better than landing a trick? Landing it with your crew watching. 🎥",
|
|
"Crews don't gatekeep spots — they open gates. Come roll with one! 🤘",
|
|
];
|
|
|
|
// Get a random joke from a specific category
|
|
function getRandomJoke(jokes: string[]): string {
|
|
return jokes[Math.floor(Math.random() * jokes.length)];
|
|
}
|
|
|
|
/**
|
|
* Sasquatch Guide - Context-aware helper for onboarding and tips
|
|
* Always visible on home and onboarding pages, can be minimized/expanded at will
|
|
*/
|
|
export function useSasquatchGuide() {
|
|
const location = useLocation();
|
|
const { user } = useCurrentUser();
|
|
const [currentMessage, setCurrentMessage] = useState<GuideMessage | undefined>();
|
|
|
|
useEffect(() => {
|
|
let message: GuideMessage | undefined;
|
|
|
|
// Show on home page
|
|
if (location.pathname === '/') {
|
|
message = {
|
|
id: 'welcome',
|
|
title: 'Welcome to SkateSpots! 🦧',
|
|
message: "Yo, I'm The Sasquatch. Keeper of boards, trails, and wild rides. Welcome to the untamed skate world on Nostr—no suits, no ads, just skaters carving their own path. Here, you own your tricks, your data, and even earn Bitcoin for leaving your mark. Connect with skaters in your hood or across the globe. No rules but shredding, no footprints but your own.",
|
|
context: 'home',
|
|
suggestedQuestions: [
|
|
'Find beginner spots',
|
|
'Any upcoming events?',
|
|
'Community stats',
|
|
'Find coaches near me',
|
|
'Gear for sale?',
|
|
'What is Nostr?',
|
|
'What are zaps?',
|
|
'Is this free?',
|
|
],
|
|
action: {
|
|
label: 'Learn More',
|
|
onClick: () => {
|
|
window.location.href = '/onboarding';
|
|
},
|
|
},
|
|
enableChat: true,
|
|
// Map homepage: don't auto-open the panel — the bubble stays minimized
|
|
// until the user taps it.
|
|
autoShow: false,
|
|
};
|
|
}
|
|
|
|
// Show on onboarding page
|
|
else if (location.pathname === '/onboarding') {
|
|
message = {
|
|
id: 'onboarding',
|
|
title: 'Getting Started 🚀',
|
|
message: "Let me help you understand the basics! Nostr is your identity, Bitcoin Lightning lets you earn sats for contributions, and zaps are instant tips. Ask me anything about getting started!",
|
|
context: 'onboarding',
|
|
suggestedQuestions: [
|
|
'How to login?',
|
|
'What is Nostr?',
|
|
'How does Nostr work?',
|
|
'What is Cashu?',
|
|
'How to use Cashu wallet?',
|
|
'What are mints?',
|
|
'What are zaps?',
|
|
'What is NWC?',
|
|
],
|
|
action: {
|
|
label: user ? 'Start exploring' : 'Login to begin',
|
|
onClick: () => {
|
|
if (user) {
|
|
window.location.href = '/map';
|
|
} else {
|
|
// Scroll to login section
|
|
const loginSection = document.getElementById('login-section');
|
|
if (loginSection) {
|
|
loginSection.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
// Highlight the section briefly
|
|
loginSection.classList.add('ring-4', 'ring-red-500/50');
|
|
setTimeout(() => {
|
|
loginSection.classList.remove('ring-4', 'ring-red-500/50');
|
|
}, 2000);
|
|
} else {
|
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
|
}
|
|
}
|
|
},
|
|
},
|
|
enableChat: true,
|
|
// Dedicated onboarding page — auto-open is helpful here.
|
|
autoShow: true,
|
|
};
|
|
}
|
|
|
|
// Show on The Lab page with random jokes
|
|
else if (location.pathname === '/lab') {
|
|
const joke = getRandomJoke(LAB_JOKES);
|
|
message = {
|
|
id: 'lab-guide',
|
|
title: 'Welcome to The Lab! 🎓',
|
|
message: `This is where the magic happens! Find coaches who can teach you anything from kickflips to darkslides, or connect with filmers to capture your best sessions. Filter by skills, check their experience, and book a session. Remember - everyone started somewhere!\n\n${joke}`,
|
|
context: 'lab',
|
|
suggestedQuestions: [
|
|
'Find coaches',
|
|
'Find filmers',
|
|
'Find photographers',
|
|
'Find video editors',
|
|
'Find a ramp builder',
|
|
'What is The Lab?',
|
|
'What is a builder?',
|
|
'How to offer coaching?',
|
|
],
|
|
action: user ? undefined : {
|
|
label: 'Login to Offer Services',
|
|
onClick: () => {
|
|
window.location.href = '/onboarding';
|
|
},
|
|
},
|
|
enableChat: true,
|
|
// The Lab: don't auto-open — the bubble stays minimized until tapped.
|
|
autoShow: false,
|
|
};
|
|
}
|
|
|
|
// Show on the Crews page
|
|
else if (location.pathname === '/crews') {
|
|
const joke = getRandomJoke(CREW_JOKES);
|
|
message = {
|
|
id: 'crews-guide',
|
|
title: 'Crews 🤘',
|
|
message: `Crews are your map-anchored skate family — the people you skate WITH, not who you hire. Every crew has home turf on the map, home spots, members and a manifesto. Members confirm from their own keys, so the roster's legit. Start your own or find your people!\n\n${joke}`,
|
|
context: undefined,
|
|
suggestedQuestions: [
|
|
'What are crews?',
|
|
'How to start a crew?',
|
|
'How is a crew different from The Lab?',
|
|
'How do members confirm?',
|
|
'What is Nostr?',
|
|
'How do zaps work?',
|
|
],
|
|
action: user ? undefined : {
|
|
label: 'Login to Start a Crew',
|
|
onClick: () => {
|
|
window.location.href = '/onboarding';
|
|
},
|
|
},
|
|
enableChat: true,
|
|
autoShow: false,
|
|
};
|
|
}
|
|
|
|
// /map: never auto-show — user opens Sasquatch by tapping the floating bubble
|
|
// The map guide context + jokes are still available in the generic fallback inside SasquatchGuide
|
|
else if (location.pathname === '/map') {
|
|
message = undefined;
|
|
}
|
|
|
|
setCurrentMessage(message);
|
|
}, [location.pathname, user]);
|
|
|
|
const dismissCurrentMessage = () => {
|
|
setCurrentMessage(undefined);
|
|
};
|
|
|
|
return {
|
|
currentMessage,
|
|
dismissCurrentMessage,
|
|
};
|
|
}
|