Prettier format pending files
This commit is contained in:
parent
e9a7c48ca8
commit
17c9fc4cfa
10 changed files with 346 additions and 302 deletions
|
|
@ -3,7 +3,7 @@ import { createClient } from "@supabase/supabase-js";
|
|||
|
||||
const supabase = createClient(
|
||||
process.env.SUPABASE_URL || "",
|
||||
process.env.SUPABASE_SERVICE_ROLE || ""
|
||||
process.env.SUPABASE_SERVICE_ROLE || "",
|
||||
);
|
||||
|
||||
interface ActivityAuthRequest {
|
||||
|
|
@ -21,10 +21,7 @@ interface UserData {
|
|||
primary_arm: string | null;
|
||||
}
|
||||
|
||||
export default async function handler(
|
||||
req: VercelRequest,
|
||||
res: VercelResponse
|
||||
) {
|
||||
export default async function handler(req: VercelRequest, res: VercelResponse) {
|
||||
if (req.method !== "POST") {
|
||||
res.setHeader("Allow", "POST");
|
||||
return res.status(405).json({ error: "Method not allowed" });
|
||||
|
|
@ -38,15 +35,20 @@ export default async function handler(
|
|||
}
|
||||
|
||||
// Verify the access token with Discord API
|
||||
const discordResponse = await fetch("https://discord.com/api/v10/users/@me", {
|
||||
headers: {
|
||||
Authorization: `Bearer ${access_token}`,
|
||||
const discordResponse = await fetch(
|
||||
"https://discord.com/api/v10/users/@me",
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${access_token}`,
|
||||
},
|
||||
},
|
||||
});
|
||||
);
|
||||
|
||||
if (!discordResponse.ok) {
|
||||
if (discordResponse.status === 401) {
|
||||
return res.status(401).json({ error: "Invalid or expired access token" });
|
||||
return res
|
||||
.status(401)
|
||||
.json({ error: "Invalid or expired access token" });
|
||||
}
|
||||
throw new Error(`Discord API error: ${discordResponse.statusText}`);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,10 +46,7 @@ const COMMANDS: CommandData[] = [
|
|||
},
|
||||
];
|
||||
|
||||
export default async function handler(
|
||||
req: VercelRequest,
|
||||
res: VercelResponse
|
||||
) {
|
||||
export default async function handler(req: VercelRequest, res: VercelResponse) {
|
||||
// Verify this is a POST request
|
||||
if (req.method !== "POST") {
|
||||
res.setHeader("Allow", "POST");
|
||||
|
|
@ -77,18 +74,16 @@ export default async function handler(
|
|||
|
||||
try {
|
||||
const rest = new REST({ version: "10" }).setToken(
|
||||
process.env.DISCORD_BOT_TOKEN!
|
||||
process.env.DISCORD_BOT_TOKEN!,
|
||||
);
|
||||
|
||||
console.log(
|
||||
`📝 Registering ${COMMANDS.length} Discord slash commands...`
|
||||
);
|
||||
console.log(`📝 Registering ${COMMANDS.length} Discord slash commands...`);
|
||||
|
||||
try {
|
||||
// Try bulk update first
|
||||
const data = await rest.put(
|
||||
Routes.applicationCommands(process.env.DISCORD_CLIENT_ID!),
|
||||
{ body: COMMANDS }
|
||||
{ body: COMMANDS },
|
||||
);
|
||||
|
||||
console.log(`✅ Successfully registered ${data.length} slash commands`);
|
||||
|
|
@ -102,7 +97,7 @@ export default async function handler(
|
|||
// Handle Error 50240 (Entry Point conflict)
|
||||
if (bulkError.code === 50240) {
|
||||
console.warn(
|
||||
"⚠️ Error 50240: Entry Point detected. Registering individually..."
|
||||
"⚠️ Error 50240: Entry Point detected. Registering individually...",
|
||||
);
|
||||
|
||||
const results = [];
|
||||
|
|
@ -114,7 +109,7 @@ export default async function handler(
|
|||
// Try to post individual command
|
||||
const posted = await rest.post(
|
||||
Routes.applicationCommands(process.env.DISCORD_CLIENT_ID!),
|
||||
{ body: command }
|
||||
{ body: command },
|
||||
);
|
||||
results.push({
|
||||
name: command.name,
|
||||
|
|
@ -141,7 +136,7 @@ export default async function handler(
|
|||
}
|
||||
|
||||
console.log(
|
||||
`✅ Registration complete: ${successCount} new, ${skipCount} already existed`
|
||||
`✅ Registration complete: ${successCount} new, ${skipCount} already existed`,
|
||||
);
|
||||
|
||||
return res.status(200).json({
|
||||
|
|
|
|||
488
client/App.tsx
488
client/App.tsx
|
|
@ -122,247 +122,265 @@ const App = () => (
|
|||
<Web3Provider>
|
||||
<DiscordProvider>
|
||||
<TooltipProvider>
|
||||
<Toaster />
|
||||
<Analytics />
|
||||
<BrowserRouter>
|
||||
<SkipAgentController />
|
||||
<PageTransition>
|
||||
<Routes>
|
||||
<Route path="/" element={<Index />} />
|
||||
<Route path="/onboarding" element={<Onboarding />} />
|
||||
<Route path="/dashboard" element={<Dashboard />} />
|
||||
<Route path="/realms" element={<Realms />} />
|
||||
<Route path="/investors" element={<Investors />} />
|
||||
<Route path="/roadmap" element={<Roadmap />} />
|
||||
<Route path="/trust" element={<Trust />} />
|
||||
<Route path="/press" element={<PressKit />} />
|
||||
<Route path="/projects" element={<Projects />} />
|
||||
<Route path="/projects/admin" element={<ProjectsAdmin />} />
|
||||
<Route path="/directory" element={<Directory />} />
|
||||
<Route path="/admin" element={<Admin />} />
|
||||
<Route path="/admin/docs-sync" element={<DocsSync />} />
|
||||
<Route path="/feed" element={<Feed />} />
|
||||
<Route path="/teams" element={<Teams />} />
|
||||
<Route path="/squads" element={<Squads />} />
|
||||
<Route path="/mentee-hub" element={<MenteeHub />} />
|
||||
<Route path="/projects/new" element={<ProjectsNew />} />
|
||||
<Route
|
||||
path="/projects/:projectId/board"
|
||||
element={<ProjectBoard />}
|
||||
/>
|
||||
<Route path="/profile" element={<Profile />} />
|
||||
<Route path="/profile/me" element={<Profile />} />
|
||||
<Route
|
||||
path="/profile/applications"
|
||||
element={<MyApplications />}
|
||||
/>
|
||||
|
||||
<Route path="/developers" element={<DevelopersDirectory />} />
|
||||
<Route
|
||||
path="/developers/me"
|
||||
element={<LegacyPassportRedirect />}
|
||||
/>
|
||||
<Route
|
||||
path="/developers/:id"
|
||||
element={<LegacyPassportRedirect />}
|
||||
/>
|
||||
<Route
|
||||
path="/profiles"
|
||||
element={<Navigate to="/developers" replace />}
|
||||
/>
|
||||
<Route
|
||||
path="/profiles/me"
|
||||
element={<LegacyPassportRedirect />}
|
||||
/>
|
||||
<Route
|
||||
path="/profiles/:id"
|
||||
element={<LegacyPassportRedirect />}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/passport"
|
||||
element={<Navigate to="/passport/me" replace />}
|
||||
/>
|
||||
<Route path="/passport/me" element={<ProfilePassport />} />
|
||||
<Route
|
||||
path="/passport/:username"
|
||||
element={<ProfilePassport />}
|
||||
/>
|
||||
<Route path="/login" element={<Login />} />
|
||||
<Route path="/signup" element={<SignupRedirect />} />
|
||||
<Route path="/reset-password" element={<ResetPassword />} />
|
||||
<Route path="/roblox-callback" element={<RobloxCallback />} />
|
||||
<Route path="/web3-callback" element={<Web3Callback />} />
|
||||
<Route path="/discord-verify" element={<DiscordVerify />} />
|
||||
|
||||
{/* Creator Network routes */}
|
||||
<Route path="/creators" element={<CreatorDirectory />} />
|
||||
<Route
|
||||
path="/creators/:username"
|
||||
element={<CreatorProfile />}
|
||||
/>
|
||||
<Route path="/opportunities" element={<OpportunitiesHub />} />
|
||||
<Route
|
||||
path="/opportunities/:id"
|
||||
element={<OpportunityDetail />}
|
||||
/>
|
||||
|
||||
{/* Service routes */}
|
||||
<Route
|
||||
path="/game-development"
|
||||
element={<GameDevelopment />}
|
||||
/>
|
||||
<Route
|
||||
path="/consulting"
|
||||
element={<DevelopmentConsulting />}
|
||||
/>
|
||||
<Route path="/mentorship" element={<MentorshipPrograms />} />
|
||||
<Route path="/engage" element={<Engage />} />
|
||||
<Route
|
||||
path="/pricing"
|
||||
element={<Navigate to="/engage" replace />}
|
||||
/>
|
||||
<Route path="/research" element={<ResearchLabs />} />
|
||||
|
||||
{/* New Arm Landing Pages */}
|
||||
<Route path="/labs" element={<Labs />} />
|
||||
<Route
|
||||
path="/labs/explore-research"
|
||||
element={<LabsExploreResearch />}
|
||||
/>
|
||||
<Route path="/labs/join-team" element={<LabsJoinTeam />} />
|
||||
<Route
|
||||
path="/labs/get-involved"
|
||||
element={<LabsGetInvolved />}
|
||||
/>
|
||||
|
||||
<Route path="/gameforge" element={<GameForge />} />
|
||||
<Route
|
||||
path="/gameforge/start-building"
|
||||
element={<GameForgeStartBuilding />}
|
||||
/>
|
||||
<Route
|
||||
path="/gameforge/view-portfolio"
|
||||
element={<GameForgeViewPortfolio />}
|
||||
/>
|
||||
<Route
|
||||
path="/gameforge/join-gameforge"
|
||||
element={<GameForgeJoinGameForge />}
|
||||
/>
|
||||
|
||||
<Route path="/corp" element={<Corp />} />
|
||||
<Route
|
||||
path="/corp/schedule-consultation"
|
||||
element={<CorpScheduleConsultation />}
|
||||
/>
|
||||
<Route
|
||||
path="/corp/view-case-studies"
|
||||
element={<CorpViewCaseStudies />}
|
||||
/>
|
||||
<Route path="/corp/contact-us" element={<CorpContactUs />} />
|
||||
|
||||
<Route path="/foundation" element={<Foundation />} />
|
||||
<Route
|
||||
path="/foundation/contribute"
|
||||
element={<FoundationContribute />}
|
||||
/>
|
||||
<Route
|
||||
path="/foundation/learn-more"
|
||||
element={<FoundationLearnMore />}
|
||||
/>
|
||||
<Route
|
||||
path="/foundation/get-involved"
|
||||
element={<FoundationGetInvolved />}
|
||||
/>
|
||||
|
||||
{/* Dev-Link routes */}
|
||||
<Route path="/dev-link" element={<DevLink />} />
|
||||
<Route
|
||||
path="/dev-link/waitlist"
|
||||
element={<DevLinkProfiles />}
|
||||
/>
|
||||
|
||||
{/* Nexus routes */}
|
||||
<Route path="/nexus" element={<Nexus />} />
|
||||
|
||||
{/* Resource routes */}
|
||||
<Route path="/docs" element={<DocsLayout />}>
|
||||
<Route index element={<DocsOverview />} />
|
||||
<Route path="tutorials" element={<DocsTutorials />} />
|
||||
<Route path="curriculum" element={<DocsCurriculum />} />
|
||||
<Toaster />
|
||||
<Analytics />
|
||||
<BrowserRouter>
|
||||
<SkipAgentController />
|
||||
<PageTransition>
|
||||
<Routes>
|
||||
<Route path="/" element={<Index />} />
|
||||
<Route path="/onboarding" element={<Onboarding />} />
|
||||
<Route path="/dashboard" element={<Dashboard />} />
|
||||
<Route path="/realms" element={<Realms />} />
|
||||
<Route path="/investors" element={<Investors />} />
|
||||
<Route path="/roadmap" element={<Roadmap />} />
|
||||
<Route path="/trust" element={<Trust />} />
|
||||
<Route path="/press" element={<PressKit />} />
|
||||
<Route path="/projects" element={<Projects />} />
|
||||
<Route path="/projects/admin" element={<ProjectsAdmin />} />
|
||||
<Route path="/directory" element={<Directory />} />
|
||||
<Route path="/admin" element={<Admin />} />
|
||||
<Route path="/admin/docs-sync" element={<DocsSync />} />
|
||||
<Route path="/feed" element={<Feed />} />
|
||||
<Route path="/teams" element={<Teams />} />
|
||||
<Route path="/squads" element={<Squads />} />
|
||||
<Route path="/mentee-hub" element={<MenteeHub />} />
|
||||
<Route path="/projects/new" element={<ProjectsNew />} />
|
||||
<Route
|
||||
path="getting-started"
|
||||
element={<DocsGettingStarted />}
|
||||
path="/projects/:projectId/board"
|
||||
element={<ProjectBoard />}
|
||||
/>
|
||||
<Route path="/profile" element={<Profile />} />
|
||||
<Route path="/profile/me" element={<Profile />} />
|
||||
<Route
|
||||
path="/profile/applications"
|
||||
element={<MyApplications />}
|
||||
/>
|
||||
<Route path="platform" element={<DocsPlatform />} />
|
||||
<Route path="api" element={<DocsApiReference />} />
|
||||
<Route path="cli" element={<DocsCli />} />
|
||||
<Route path="examples" element={<DocsExamples />} />
|
||||
<Route path="integrations" element={<DocsIntegrations />} />
|
||||
</Route>
|
||||
<Route path="/tutorials" element={<Tutorials />} />
|
||||
<Route path="/blog" element={<Blog />} />
|
||||
<Route path="/blog/:slug" element={<BlogPost />} />
|
||||
<Route path="/community" element={<Community />} />
|
||||
<Route
|
||||
path="/community/teams"
|
||||
element={<FoundationTeams />}
|
||||
/>
|
||||
<Route
|
||||
path="/community/about"
|
||||
element={<FoundationAbout />}
|
||||
/>
|
||||
<Route
|
||||
path="/community/mentorship"
|
||||
element={<MentorshipRequest />}
|
||||
/>
|
||||
<Route
|
||||
path="/community/mentorship/apply"
|
||||
element={<MentorApply />}
|
||||
/>
|
||||
<Route
|
||||
path="/community/mentor/:username"
|
||||
element={<MentorProfile />}
|
||||
/>
|
||||
<Route path="/community/:tabId" element={<Community />} />
|
||||
<Route path="/staff" element={<Staff />} />
|
||||
<Route path="/support" element={<Support />} />
|
||||
<Route path="/status" element={<Status />} />
|
||||
<Route path="/changelog" element={<Changelog />} />
|
||||
|
||||
{/* Informational routes */}
|
||||
<Route path="/wix" element={<Wix />} />
|
||||
<Route
|
||||
path="/wix/case-studies"
|
||||
element={<WixCaseStudies />}
|
||||
/>
|
||||
<Route path="/wix/faq" element={<WixFaq />} />
|
||||
<Route path="/about" element={<About />} />
|
||||
<Route path="/contact" element={<Contact />} />
|
||||
<Route path="/get-started" element={<GetStarted />} />
|
||||
<Route path="/explore" element={<Explore />} />
|
||||
<Route path="/services" element={<Services />} />
|
||||
<Route path="/careers" element={<Careers />} />
|
||||
<Route
|
||||
path="/developers"
|
||||
element={<DevelopersDirectory />}
|
||||
/>
|
||||
<Route
|
||||
path="/developers/me"
|
||||
element={<LegacyPassportRedirect />}
|
||||
/>
|
||||
<Route
|
||||
path="/developers/:id"
|
||||
element={<LegacyPassportRedirect />}
|
||||
/>
|
||||
<Route
|
||||
path="/profiles"
|
||||
element={<Navigate to="/developers" replace />}
|
||||
/>
|
||||
<Route
|
||||
path="/profiles/me"
|
||||
element={<LegacyPassportRedirect />}
|
||||
/>
|
||||
<Route
|
||||
path="/profiles/:id"
|
||||
element={<LegacyPassportRedirect />}
|
||||
/>
|
||||
|
||||
{/* Legal routes */}
|
||||
<Route path="/privacy" element={<Privacy />} />
|
||||
<Route path="/terms" element={<Terms />} />
|
||||
<Route
|
||||
path="/passport"
|
||||
element={<Navigate to="/passport/me" replace />}
|
||||
/>
|
||||
<Route path="/passport/me" element={<ProfilePassport />} />
|
||||
<Route
|
||||
path="/passport/:username"
|
||||
element={<ProfilePassport />}
|
||||
/>
|
||||
<Route path="/login" element={<Login />} />
|
||||
<Route path="/signup" element={<SignupRedirect />} />
|
||||
<Route path="/reset-password" element={<ResetPassword />} />
|
||||
<Route
|
||||
path="/roblox-callback"
|
||||
element={<RobloxCallback />}
|
||||
/>
|
||||
<Route path="/web3-callback" element={<Web3Callback />} />
|
||||
<Route path="/discord-verify" element={<DiscordVerify />} />
|
||||
|
||||
{/* Discord routes */}
|
||||
<Route path="/activity" element={<Activity />} />
|
||||
<Route path="/discord" element={<DiscordActivity />} />
|
||||
<Route
|
||||
path="/discord/callback"
|
||||
element={<DiscordOAuthCallback />}
|
||||
/>
|
||||
{/* Creator Network routes */}
|
||||
<Route path="/creators" element={<CreatorDirectory />} />
|
||||
<Route
|
||||
path="/creators/:username"
|
||||
element={<CreatorProfile />}
|
||||
/>
|
||||
<Route
|
||||
path="/opportunities"
|
||||
element={<OpportunitiesHub />}
|
||||
/>
|
||||
<Route
|
||||
path="/opportunities/:id"
|
||||
element={<OpportunityDetail />}
|
||||
/>
|
||||
|
||||
{/* Explicit 404 route for static hosting fallbacks */}
|
||||
<Route path="/404" element={<FourOhFourPage />} />
|
||||
{/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */}
|
||||
<Route path="*" element={<FourOhFourPage />} />
|
||||
</Routes>
|
||||
</PageTransition>
|
||||
</BrowserRouter>
|
||||
{/* Service routes */}
|
||||
<Route
|
||||
path="/game-development"
|
||||
element={<GameDevelopment />}
|
||||
/>
|
||||
<Route
|
||||
path="/consulting"
|
||||
element={<DevelopmentConsulting />}
|
||||
/>
|
||||
<Route
|
||||
path="/mentorship"
|
||||
element={<MentorshipPrograms />}
|
||||
/>
|
||||
<Route path="/engage" element={<Engage />} />
|
||||
<Route
|
||||
path="/pricing"
|
||||
element={<Navigate to="/engage" replace />}
|
||||
/>
|
||||
<Route path="/research" element={<ResearchLabs />} />
|
||||
|
||||
{/* New Arm Landing Pages */}
|
||||
<Route path="/labs" element={<Labs />} />
|
||||
<Route
|
||||
path="/labs/explore-research"
|
||||
element={<LabsExploreResearch />}
|
||||
/>
|
||||
<Route path="/labs/join-team" element={<LabsJoinTeam />} />
|
||||
<Route
|
||||
path="/labs/get-involved"
|
||||
element={<LabsGetInvolved />}
|
||||
/>
|
||||
|
||||
<Route path="/gameforge" element={<GameForge />} />
|
||||
<Route
|
||||
path="/gameforge/start-building"
|
||||
element={<GameForgeStartBuilding />}
|
||||
/>
|
||||
<Route
|
||||
path="/gameforge/view-portfolio"
|
||||
element={<GameForgeViewPortfolio />}
|
||||
/>
|
||||
<Route
|
||||
path="/gameforge/join-gameforge"
|
||||
element={<GameForgeJoinGameForge />}
|
||||
/>
|
||||
|
||||
<Route path="/corp" element={<Corp />} />
|
||||
<Route
|
||||
path="/corp/schedule-consultation"
|
||||
element={<CorpScheduleConsultation />}
|
||||
/>
|
||||
<Route
|
||||
path="/corp/view-case-studies"
|
||||
element={<CorpViewCaseStudies />}
|
||||
/>
|
||||
<Route
|
||||
path="/corp/contact-us"
|
||||
element={<CorpContactUs />}
|
||||
/>
|
||||
|
||||
<Route path="/foundation" element={<Foundation />} />
|
||||
<Route
|
||||
path="/foundation/contribute"
|
||||
element={<FoundationContribute />}
|
||||
/>
|
||||
<Route
|
||||
path="/foundation/learn-more"
|
||||
element={<FoundationLearnMore />}
|
||||
/>
|
||||
<Route
|
||||
path="/foundation/get-involved"
|
||||
element={<FoundationGetInvolved />}
|
||||
/>
|
||||
|
||||
{/* Dev-Link routes */}
|
||||
<Route path="/dev-link" element={<DevLink />} />
|
||||
<Route
|
||||
path="/dev-link/waitlist"
|
||||
element={<DevLinkProfiles />}
|
||||
/>
|
||||
|
||||
{/* Nexus routes */}
|
||||
<Route path="/nexus" element={<Nexus />} />
|
||||
|
||||
{/* Resource routes */}
|
||||
<Route path="/docs" element={<DocsLayout />}>
|
||||
<Route index element={<DocsOverview />} />
|
||||
<Route path="tutorials" element={<DocsTutorials />} />
|
||||
<Route path="curriculum" element={<DocsCurriculum />} />
|
||||
<Route
|
||||
path="getting-started"
|
||||
element={<DocsGettingStarted />}
|
||||
/>
|
||||
<Route path="platform" element={<DocsPlatform />} />
|
||||
<Route path="api" element={<DocsApiReference />} />
|
||||
<Route path="cli" element={<DocsCli />} />
|
||||
<Route path="examples" element={<DocsExamples />} />
|
||||
<Route
|
||||
path="integrations"
|
||||
element={<DocsIntegrations />}
|
||||
/>
|
||||
</Route>
|
||||
<Route path="/tutorials" element={<Tutorials />} />
|
||||
<Route path="/blog" element={<Blog />} />
|
||||
<Route path="/blog/:slug" element={<BlogPost />} />
|
||||
<Route path="/community" element={<Community />} />
|
||||
<Route
|
||||
path="/community/teams"
|
||||
element={<FoundationTeams />}
|
||||
/>
|
||||
<Route
|
||||
path="/community/about"
|
||||
element={<FoundationAbout />}
|
||||
/>
|
||||
<Route
|
||||
path="/community/mentorship"
|
||||
element={<MentorshipRequest />}
|
||||
/>
|
||||
<Route
|
||||
path="/community/mentorship/apply"
|
||||
element={<MentorApply />}
|
||||
/>
|
||||
<Route
|
||||
path="/community/mentor/:username"
|
||||
element={<MentorProfile />}
|
||||
/>
|
||||
<Route path="/community/:tabId" element={<Community />} />
|
||||
<Route path="/staff" element={<Staff />} />
|
||||
<Route path="/support" element={<Support />} />
|
||||
<Route path="/status" element={<Status />} />
|
||||
<Route path="/changelog" element={<Changelog />} />
|
||||
|
||||
{/* Informational routes */}
|
||||
<Route path="/wix" element={<Wix />} />
|
||||
<Route
|
||||
path="/wix/case-studies"
|
||||
element={<WixCaseStudies />}
|
||||
/>
|
||||
<Route path="/wix/faq" element={<WixFaq />} />
|
||||
<Route path="/about" element={<About />} />
|
||||
<Route path="/contact" element={<Contact />} />
|
||||
<Route path="/get-started" element={<GetStarted />} />
|
||||
<Route path="/explore" element={<Explore />} />
|
||||
<Route path="/services" element={<Services />} />
|
||||
<Route path="/careers" element={<Careers />} />
|
||||
|
||||
{/* Legal routes */}
|
||||
<Route path="/privacy" element={<Privacy />} />
|
||||
<Route path="/terms" element={<Terms />} />
|
||||
|
||||
{/* Discord routes */}
|
||||
<Route path="/activity" element={<Activity />} />
|
||||
<Route path="/discord" element={<DiscordActivity />} />
|
||||
<Route
|
||||
path="/discord/callback"
|
||||
element={<DiscordOAuthCallback />}
|
||||
/>
|
||||
|
||||
{/* Explicit 404 route for static hosting fallbacks */}
|
||||
<Route path="/404" element={<FourOhFourPage />} />
|
||||
{/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */}
|
||||
<Route path="*" element={<FourOhFourPage />} />
|
||||
</Routes>
|
||||
</PageTransition>
|
||||
</BrowserRouter>
|
||||
</TooltipProvider>
|
||||
</DiscordProvider>
|
||||
</Web3Provider>
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ export function AdminDiscordManagement() {
|
|||
setRegisterSuccess(null);
|
||||
|
||||
const adminToken = prompt(
|
||||
"Enter admin registration token (from environment variables):"
|
||||
"Enter admin registration token (from environment variables):",
|
||||
);
|
||||
if (!adminToken) {
|
||||
setRegisterError("Registration cancelled");
|
||||
|
|
@ -149,7 +149,7 @@ export function AdminDiscordManagement() {
|
|||
|
||||
const data = await response.json();
|
||||
setRegisterSuccess(
|
||||
data.message || "Discord commands registered successfully!"
|
||||
data.message || "Discord commands registered successfully!",
|
||||
);
|
||||
setTimeout(() => setRegisterSuccess(null), 5000);
|
||||
} catch (err) {
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ export const useDiscordActivity = () => {
|
|||
const context = useContext(DiscordActivityContext);
|
||||
if (!context) {
|
||||
throw new Error(
|
||||
"useDiscordActivity must be used within DiscordActivityProvider"
|
||||
"useDiscordActivity must be used within DiscordActivityProvider",
|
||||
);
|
||||
}
|
||||
return context;
|
||||
|
|
@ -41,9 +41,9 @@ interface DiscordActivityProviderProps {
|
|||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export const DiscordActivityProvider: React.FC<DiscordActivityProviderProps> = ({
|
||||
children,
|
||||
}) => {
|
||||
export const DiscordActivityProvider: React.FC<
|
||||
DiscordActivityProviderProps
|
||||
> = ({ children }) => {
|
||||
const [isActivity, setIsActivity] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [user, setUser] = useState<DiscordUser | null>(null);
|
||||
|
|
@ -64,11 +64,10 @@ export const DiscordActivityProvider: React.FC<DiscordActivityProviderProps> = (
|
|||
setIsLoading(true);
|
||||
|
||||
// Import the Discord SDK dynamically
|
||||
const { DiscordSDK } = await import(
|
||||
"@discord/embedded-app-sdk"
|
||||
);
|
||||
const { DiscordSDK } = await import("@discord/embedded-app-sdk");
|
||||
|
||||
const clientId = import.meta.env.VITE_DISCORD_CLIENT_ID || "578971245454950421";
|
||||
const clientId =
|
||||
import.meta.env.VITE_DISCORD_CLIENT_ID || "578971245454950421";
|
||||
|
||||
const sdk = new DiscordSDK({
|
||||
clientId,
|
||||
|
|
@ -119,7 +118,7 @@ export const DiscordActivityProvider: React.FC<DiscordActivityProviderProps> = (
|
|||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
access_token: currentUser.access_token || ""
|
||||
access_token: currentUser.access_token || "",
|
||||
}),
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -132,7 +132,9 @@ export default function Activity() {
|
|||
<code className="bg-blue-800 px-2 py-1 rounded">/profile</code>,{" "}
|
||||
<code className="bg-blue-800 px-2 py-1 rounded">/set-realm</code>,
|
||||
and{" "}
|
||||
<code className="bg-blue-800 px-2 py-1 rounded">/verify-role</code>{" "}
|
||||
<code className="bg-blue-800 px-2 py-1 rounded">
|
||||
/verify-role
|
||||
</code>{" "}
|
||||
to manage your account within Discord.
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -114,9 +114,7 @@ client.login(process.env.DISCORD_BOT_TOKEN);
|
|||
client.once("ready", () => {
|
||||
console.log(`✅ Bot logged in as ${client.user.tag}`);
|
||||
console.log(`📡 Listening in ${client.guilds.cache.size} server(s)`);
|
||||
console.log(
|
||||
"ℹ️ Commands are registered via: npm run register-commands"
|
||||
);
|
||||
console.log("ℹ️ Commands are registered via: npm run register-commands");
|
||||
|
||||
// Set bot status
|
||||
client.user.setActivity("/verify to link your AeThex account", {
|
||||
|
|
|
|||
|
|
@ -4,16 +4,13 @@ const path = require("path");
|
|||
require("dotenv").config();
|
||||
|
||||
// Validate environment variables
|
||||
const requiredEnvVars = [
|
||||
"DISCORD_BOT_TOKEN",
|
||||
"DISCORD_CLIENT_ID",
|
||||
];
|
||||
const requiredEnvVars = ["DISCORD_BOT_TOKEN", "DISCORD_CLIENT_ID"];
|
||||
|
||||
const missingVars = requiredEnvVars.filter((envVar) => !process.env[envVar]);
|
||||
if (missingVars.length > 0) {
|
||||
console.error(
|
||||
"❌ FATAL ERROR: Missing required environment variables:",
|
||||
missingVars.join(", ")
|
||||
missingVars.join(", "),
|
||||
);
|
||||
console.error("\nPlease set these before running command registration:");
|
||||
missingVars.forEach((envVar) => {
|
||||
|
|
@ -43,55 +40,68 @@ for (const file of commandFiles) {
|
|||
async function registerCommands() {
|
||||
try {
|
||||
const rest = new REST({ version: "10" }).setToken(
|
||||
process.env.DISCORD_BOT_TOKEN
|
||||
process.env.DISCORD_BOT_TOKEN,
|
||||
);
|
||||
|
||||
console.log(`\n📝 Registering ${commands.length} slash commands...`);
|
||||
console.log("⚠️ This will co-exist with Discord's auto-generated Entry Point command.\n");
|
||||
console.log(
|
||||
"⚠️ This will co-exist with Discord's auto-generated Entry Point command.\n",
|
||||
);
|
||||
|
||||
try {
|
||||
const data = await rest.put(
|
||||
Routes.applicationCommands(process.env.DISCORD_CLIENT_ID),
|
||||
{ body: commands }
|
||||
{ body: commands },
|
||||
);
|
||||
console.log(`✅ Successfully registered ${data.length} slash commands.`);
|
||||
console.log("\n🎉 Command registration complete!");
|
||||
console.log("ℹ️ Your commands are now live in Discord.");
|
||||
console.log("ℹ️ The Entry Point command (for Activities) will be managed by Discord.\n");
|
||||
console.log(
|
||||
"ℹ️ The Entry Point command (for Activities) will be managed by Discord.\n",
|
||||
);
|
||||
} catch (error) {
|
||||
// Handle Entry Point command conflict
|
||||
if (error.code === 50240) {
|
||||
console.warn(
|
||||
"⚠️ Error 50240: Entry Point command detected (Discord Activity enabled)."
|
||||
"⚠️ Error 50240: Entry Point command detected (Discord Activity enabled).",
|
||||
);
|
||||
console.warn("Registering commands individually...\n");
|
||||
|
||||
|
||||
let successCount = 0;
|
||||
for (const command of commands) {
|
||||
try {
|
||||
await rest.post(
|
||||
Routes.applicationCommands(process.env.DISCORD_CLIENT_ID),
|
||||
{ body: command }
|
||||
{ body: command },
|
||||
);
|
||||
successCount++;
|
||||
} catch (postError) {
|
||||
if (postError.code === 50045) {
|
||||
console.warn(` ⚠️ ${command.name}: Already registered (skipping)`);
|
||||
console.warn(
|
||||
` ⚠️ ${command.name}: Already registered (skipping)`,
|
||||
);
|
||||
} else {
|
||||
console.error(` ❌ ${command.name}: ${postError.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`\n✅ Registered ${successCount} slash commands (individual mode).`);
|
||||
|
||||
console.log(
|
||||
`\n✅ Registered ${successCount} slash commands (individual mode).`,
|
||||
);
|
||||
console.log("🎉 Command registration complete!");
|
||||
console.log("ℹ️ The Entry Point command will be managed by Discord.\n");
|
||||
console.log(
|
||||
"ℹ️ The Entry Point command will be managed by Discord.\n",
|
||||
);
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("❌ Fatal error registering commands:", error.message || error);
|
||||
console.error(
|
||||
"❌ Fatal error registering commands:",
|
||||
error.message || error,
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,11 +11,13 @@ If you can't run `npm` in your development environment, follow this guide to dep
|
|||
Add these to your deployment platform (Vercel, PebbleHost):
|
||||
|
||||
### Vercel (Frontend)
|
||||
|
||||
```
|
||||
VITE_DISCORD_CLIENT_ID=578971245454950421
|
||||
```
|
||||
|
||||
### PebbleHost (Discord Bot)
|
||||
|
||||
```
|
||||
DISCORD_BOT_TOKEN=<your-token>
|
||||
DISCORD_CLIENT_ID=578971245454950421
|
||||
|
|
@ -26,6 +28,7 @@ BOT_PORT=3000
|
|||
```
|
||||
|
||||
### Vercel (Backend - for command registration)
|
||||
|
||||
```
|
||||
DISCORD_BOT_TOKEN=<your-token>
|
||||
DISCORD_CLIENT_ID=578971245454950421
|
||||
|
|
@ -68,15 +71,15 @@ You can add a button to `/admin` panel that triggers this endpoint:
|
|||
|
||||
```typescript
|
||||
async function registerCommands() {
|
||||
const response = await fetch('/api/discord/admin-register-commands', {
|
||||
method: 'POST',
|
||||
const response = await fetch("/api/discord/admin-register-commands", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
'Authorization': `Bearer ${process.env.DISCORD_ADMIN_REGISTER_TOKEN}`,
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${process.env.DISCORD_ADMIN_REGISTER_TOKEN}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
const data = await response.json();
|
||||
console.log('Registration result:', data);
|
||||
console.log("Registration result:", data);
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -131,10 +134,12 @@ Command registration happens via the API endpoint (Step 3), not on bot startup.
|
|||
### Error 50240: "Cannot remove Entry Point command"
|
||||
|
||||
**This happens if:**
|
||||
|
||||
- You enable Activities, then the bot tries to register commands via bulk update
|
||||
- The bot is trying to overwrite the auto-generated Entry Point command
|
||||
|
||||
**Solution:**
|
||||
|
||||
- ✅ Your bot code has been fixed (bot no longer registers on startup)
|
||||
- Just call the `/api/discord/admin-register-commands` endpoint (Step 3)
|
||||
- The endpoint handles Error 50240 gracefully
|
||||
|
|
@ -142,6 +147,7 @@ Command registration happens via the API endpoint (Step 3), not on bot startup.
|
|||
### Activity not loading in Discord
|
||||
|
||||
**Check:**
|
||||
|
||||
1. Activities enabled in Discord Developer Portal ✅
|
||||
2. Activity URL is set to `https://aethex.dev/activity` (not an IP) ✅
|
||||
3. Frontend is deployed to Vercel ✅
|
||||
|
|
@ -151,6 +157,7 @@ Command registration happens via the API endpoint (Step 3), not on bot startup.
|
|||
### "Unauthorized" error when calling register endpoint
|
||||
|
||||
**Check:**
|
||||
|
||||
1. `DISCORD_ADMIN_REGISTER_TOKEN` is set in Vercel environment variables
|
||||
2. You're passing the correct token in the `Authorization: Bearer` header
|
||||
3. The token matches exactly (no extra spaces)
|
||||
|
|
@ -158,6 +165,7 @@ Command registration happens via the API endpoint (Step 3), not on bot startup.
|
|||
### Bot not responding to commands
|
||||
|
||||
**Check:**
|
||||
|
||||
1. Bot is online on PebbleHost (check logs)
|
||||
2. Commands are registered (call `/api/discord/admin-register-commands` and check response)
|
||||
3. Response shows commands registered successfully
|
||||
|
|
@ -167,13 +175,13 @@ Command registration happens via the API endpoint (Step 3), not on bot startup.
|
|||
|
||||
## Quick Reference
|
||||
|
||||
| What | How |
|
||||
|------|-----|
|
||||
| Enable Activities | Discord Developer Portal → Settings → Activities → Enable |
|
||||
| What | How |
|
||||
| ----------------- | -------------------------------------------------------------- |
|
||||
| Enable Activities | Discord Developer Portal → Settings → Activities → Enable |
|
||||
| Register Commands | POST to `/api/discord/admin-register-commands` with auth token |
|
||||
| Deploy Bot | Push to PebbleHost, bot starts with `npm start` |
|
||||
| Deploy Frontend | Push to GitHub, Vercel auto-deploys |
|
||||
| Test Activity | Open Discord, click Activity button, should load |
|
||||
| Deploy Bot | Push to PebbleHost, bot starts with `npm start` |
|
||||
| Deploy Frontend | Push to GitHub, Vercel auto-deploys |
|
||||
| Test Activity | Open Discord, click Activity button, should load |
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -209,6 +217,6 @@ Plus the auto-generated **Entry Point** command (managed by Discord for Activiti
|
|||
✅ Everything can be deployed via web interfaces
|
||||
✅ Commands registered via API endpoint
|
||||
✅ Error 50240 handled automatically
|
||||
✅ Activity loads instantly in Discord
|
||||
✅ Activity loads instantly in Discord
|
||||
|
||||
**You're all set!** 🚀
|
||||
|
|
|
|||
|
|
@ -24,10 +24,12 @@ Click this button.
|
|||
A popup will appear asking for your **admin registration token**.
|
||||
|
||||
This token is:
|
||||
|
||||
- Set in your Vercel environment variables as `DISCORD_ADMIN_REGISTER_TOKEN`
|
||||
- A random secure string (e.g., `sk-admin-aethex-discord-2024`)
|
||||
|
||||
**Example popup:**
|
||||
|
||||
```
|
||||
Enter admin registration token (from environment variables):
|
||||
[_________________________] [OK] [Cancel]
|
||||
|
|
@ -40,16 +42,19 @@ The button will show **"Registering..."** with a spinning loader.
|
|||
Once complete, you'll see one of:
|
||||
|
||||
**✅ Success:**
|
||||
|
||||
```
|
||||
✅ Registered 5 new commands (Entry Point already exists)
|
||||
```
|
||||
|
||||
**⚠️ Partial Success (Error 50240):**
|
||||
|
||||
```
|
||||
✅ Registered 5 new commands (Entry Point managed by Discord)
|
||||
```
|
||||
|
||||
**❌ Error:**
|
||||
|
||||
```
|
||||
❌ Invalid or expired access token
|
||||
```
|
||||
|
|
@ -77,6 +82,7 @@ Plus Discord's auto-generated **"Entry Point"** command (for Discord Activities)
|
|||
**Issue:** Getting this error when registering.
|
||||
|
||||
**Solution:**
|
||||
|
||||
1. Check your `DISCORD_ADMIN_REGISTER_TOKEN` environment variable in Vercel
|
||||
2. Make sure you entered the token exactly as it's set (case-sensitive)
|
||||
3. Verify token doesn't have extra spaces
|
||||
|
|
@ -86,6 +92,7 @@ Plus Discord's auto-generated **"Entry Point"** command (for Discord Activities)
|
|||
**Issue:** Generic error when clicking the button.
|
||||
|
||||
**Check:**
|
||||
|
||||
1. Is your bot deployed on PebbleHost?
|
||||
2. Are your `DISCORD_BOT_TOKEN` and `DISCORD_CLIENT_ID` env vars set on Vercel (backend)?
|
||||
3. Open browser console (F12) → Network tab → Check the POST request to `/api/discord/admin-register-commands`
|
||||
|
|
@ -93,6 +100,7 @@ Plus Discord's auto-generated **"Entry Point"** command (for Discord Activities)
|
|||
### "Entry Point command already exists" (Not an Error)
|
||||
|
||||
**This is expected!** When you enable Discord Activities:
|
||||
|
||||
1. Discord auto-creates an "Entry Point" command
|
||||
2. Our script recognizes this and doesn't try to overwrite it
|
||||
3. Your bot's 5 commands live alongside it peacefully
|
||||
|
|
@ -102,6 +110,7 @@ Plus Discord's auto-generated **"Entry Point"** command (for Discord Activities)
|
|||
## Environment Variables Required
|
||||
|
||||
**On Vercel (Backend):**
|
||||
|
||||
```
|
||||
DISCORD_BOT_TOKEN=<your-bot-token>
|
||||
DISCORD_CLIENT_ID=578971245454950421
|
||||
|
|
@ -109,6 +118,7 @@ DISCORD_ADMIN_REGISTER_TOKEN=sk-admin-aethex-discord-2024
|
|||
```
|
||||
|
||||
**On PebbleHost (Bot):**
|
||||
|
||||
```
|
||||
DISCORD_BOT_TOKEN=<your-bot-token>
|
||||
DISCORD_CLIENT_ID=578971245454950421
|
||||
|
|
@ -124,6 +134,7 @@ SUPABASE_SERVICE_ROLE=<your-service-role>
|
|||
If the admin button doesn't work, you can also register commands using:
|
||||
|
||||
### curl (if you have PebbleHost console access)
|
||||
|
||||
```bash
|
||||
curl -X POST https://aethex.dev/api/discord/admin-register-commands \
|
||||
-H "Authorization: Bearer YOUR_DISCORD_ADMIN_REGISTER_TOKEN" \
|
||||
|
|
@ -131,6 +142,7 @@ curl -X POST https://aethex.dev/api/discord/admin-register-commands \
|
|||
```
|
||||
|
||||
### Postman
|
||||
|
||||
1. Create POST request to `https://aethex.dev/api/discord/admin-register-commands`
|
||||
2. Add header: `Authorization: Bearer YOUR_DISCORD_ADMIN_REGISTER_TOKEN`
|
||||
3. Click Send
|
||||
|
|
@ -142,6 +154,6 @@ curl -X POST https://aethex.dev/api/discord/admin-register-commands \
|
|||
✅ Click "Register Commands" in Admin → Discord tab
|
||||
✅ Enter your admin token
|
||||
✅ Wait for success confirmation
|
||||
✅ Commands are now live in Discord
|
||||
✅ Commands are now live in Discord
|
||||
|
||||
Done! 🎉
|
||||
|
|
|
|||
Loading…
Reference in a new issue