From 8c2dee5d9eaed6b76dda3d9149df9df69925b30a Mon Sep 17 00:00:00 2001
From: sirpiglr <49359077-sirpiglr@users.noreply.replit.com>
Date: Wed, 10 Dec 2025 02:36:59 +0000
Subject: [PATCH] Add pricing page and update navigation links
Replaced `.single()` with `.maybeSingle()` in multiple command files to handle cases where no record is found, and added a new /pricing route and navigation links to the UI.
Replit-Commit-Author: Agent
Replit-Commit-Session-Id: aed2e46d-25bb-4b73-81a1-bb9e8437c261
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
Replit-Commit-Event-Id: e91d020a-35a6-4add-9945-887dd3ecae9f
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/3bdfff67-975a-46ad-9845-fbb6b4a4c4b5/aed2e46d-25bb-4b73-81a1-bb9e8437c261/tdDjujk
Replit-Helium-Checkpoint-Created: true
---
.replit | 4 +
aethex-bot/commands/badges.js | 4 +-
aethex-bot/commands/daily.js | 4 +-
aethex-bot/commands/foundation.js | 4 +-
aethex-bot/commands/leaderboard.js | 6 +-
aethex-bot/commands/post.js | 6 +-
aethex-bot/commands/prestige.js | 6 +-
aethex-bot/commands/profile.js | 4 +-
aethex-bot/commands/rank.js | 4 +-
aethex-bot/commands/set-realm.js | 2 +-
aethex-bot/commands/stats.js | 6 +-
aethex-bot/commands/studio.js | 4 +-
aethex-bot/commands/unlink.js | 2 +-
aethex-bot/commands/userinfo.js | 4 +-
aethex-bot/commands/verify-role.js | 4 +-
aethex-bot/commands/verify.js | 2 +-
aethex-bot/public/federation.html | 2 +-
aethex-bot/public/index.html | 3 +-
aethex-bot/public/pricing.html | 660 +++++++++++++++++++++++++++++
aethex-bot/server/webServer.js | 35 ++
20 files changed, 733 insertions(+), 33 deletions(-)
create mode 100644 aethex-bot/public/pricing.html
diff --git a/.replit b/.replit
index 9585c0f..a798d30 100644
--- a/.replit
+++ b/.replit
@@ -21,6 +21,10 @@ externalPort = 80
localPort = 8080
externalPort = 8080
+[[ports]]
+localPort = 34785
+externalPort = 3000
+
[workflows]
runButton = "Project"
diff --git a/aethex-bot/commands/badges.js b/aethex-bot/commands/badges.js
index 38986ae..1592007 100644
--- a/aethex-bot/commands/badges.js
+++ b/aethex-bot/commands/badges.js
@@ -57,7 +57,7 @@ module.exports = {
.from('discord_links')
.select('user_id')
.eq('discord_id', target.id)
- .single();
+ .maybeSingle();
if (!link) {
return interaction.editReply({
@@ -73,7 +73,7 @@ module.exports = {
.from('user_profiles')
.select('username, avatar_url, badges, xp, daily_streak')
.eq('id', link.user_id)
- .single();
+ .maybeSingle();
let earnedBadges = [];
diff --git a/aethex-bot/commands/daily.js b/aethex-bot/commands/daily.js
index e31928f..e8f1ceb 100644
--- a/aethex-bot/commands/daily.js
+++ b/aethex-bot/commands/daily.js
@@ -78,7 +78,7 @@ async function handleFederatedDaily(interaction, supabase, client) {
.from('discord_links')
.select('user_id')
.eq('discord_id', interaction.user.id)
- .single();
+ .maybeSingle();
if (!link) {
return interaction.editReply({
@@ -94,7 +94,7 @@ async function handleFederatedDaily(interaction, supabase, client) {
.from('user_profiles')
.select('xp, daily_streak, last_daily, prestige_level, total_xp_earned')
.eq('id', link.user_id)
- .single();
+ .maybeSingle();
const now = new Date();
const lastDaily = profile?.last_daily ? new Date(profile.last_daily) : null;
diff --git a/aethex-bot/commands/foundation.js b/aethex-bot/commands/foundation.js
index b99851a..e9a6694 100644
--- a/aethex-bot/commands/foundation.js
+++ b/aethex-bot/commands/foundation.js
@@ -22,14 +22,14 @@ module.exports = {
.from('discord_links')
.select('user_id')
.eq('discord_id', target.id)
- .single();
+ .maybeSingle();
if (link) {
const { data: contribution } = await supabase
.from('foundation_contributions')
.select('total_donated, volunteer_hours, badges')
.eq('user_id', link.user_id)
- .single();
+ .maybeSingle();
contributionData = contribution;
}
diff --git a/aethex-bot/commands/leaderboard.js b/aethex-bot/commands/leaderboard.js
index d0e20a9..d959bc2 100644
--- a/aethex-bot/commands/leaderboard.js
+++ b/aethex-bot/commands/leaderboard.js
@@ -319,7 +319,7 @@ async function handleFederatedLeaderboard(interaction, supabase, category) {
.from("user_profiles")
.select("username, full_name, avatar_url")
.eq("id", userId)
- .single();
+ .maybeSingle();
if (profile) {
leaderboardData.push({
@@ -355,7 +355,7 @@ async function handleFederatedLeaderboard(interaction, supabase, category) {
.from("user_profiles")
.select("username, full_name, avatar_url")
.eq("id", userId)
- .single();
+ .maybeSingle();
if (profile) {
leaderboardData.push({
@@ -381,7 +381,7 @@ async function handleFederatedLeaderboard(interaction, supabase, category) {
.from("user_profiles")
.select("username, full_name, avatar_url")
.eq("id", creator.user_id)
- .single();
+ .maybeSingle();
if (profile) {
const badges = [];
diff --git a/aethex-bot/commands/post.js b/aethex-bot/commands/post.js
index 08a1e7f..3febaf8 100644
--- a/aethex-bot/commands/post.js
+++ b/aethex-bot/commands/post.js
@@ -49,7 +49,7 @@ module.exports = {
.from("discord_links")
.select("user_id, primary_arm")
.eq("discord_id", interaction.user.id)
- .single();
+ .maybeSingle();
if (!link) {
const embed = new EmbedBuilder()
@@ -66,7 +66,7 @@ module.exports = {
.from("user_profiles")
.select("username, full_name, avatar_url")
.eq("id", link.user_id)
- .single();
+ .maybeSingle();
const content = interaction.options.getString("content");
const category = interaction.options.getString("category") || "general";
@@ -100,7 +100,7 @@ module.exports = {
discord_author_avatar: interaction.user.displayAvatarURL(),
})
.select()
- .single();
+ .maybeSingle();
if (error) throw error;
diff --git a/aethex-bot/commands/prestige.js b/aethex-bot/commands/prestige.js
index 05e2166..4edd210 100644
--- a/aethex-bot/commands/prestige.js
+++ b/aethex-bot/commands/prestige.js
@@ -98,7 +98,7 @@ async function viewPrestige(interaction, supabase, mode) {
.from('discord_links')
.select('user_id')
.eq('discord_id', target.id)
- .single();
+ .maybeSingle();
if (!link) {
return interaction.editReply({
@@ -114,7 +114,7 @@ async function viewPrestige(interaction, supabase, mode) {
.from('user_profiles')
.select('username, xp, prestige_level, total_xp_earned')
.eq('id', link.user_id)
- .single();
+ .maybeSingle();
const prestige = profile?.prestige_level || 0;
const totalXpEarned = profile?.total_xp_earned || profile?.xp || 0;
@@ -295,7 +295,7 @@ async function prestigeUp(interaction, supabase, client, mode) {
.from('user_profiles')
.select('username, xp, prestige_level, total_xp_earned')
.eq('id', link.user_id)
- .single();
+ .maybeSingle();
const currentXp = profile?.xp || 0;
const level = Math.floor(Math.sqrt(currentXp / 100));
diff --git a/aethex-bot/commands/profile.js b/aethex-bot/commands/profile.js
index 4111527..4d451f0 100644
--- a/aethex-bot/commands/profile.js
+++ b/aethex-bot/commands/profile.js
@@ -107,7 +107,7 @@ async function handleFederatedProfile(interaction, supabase, targetUser) {
.from("discord_links")
.select("user_id, primary_arm")
.eq("discord_id", targetUser.id)
- .single();
+ .maybeSingle();
if (!link) {
const embed = new EmbedBuilder()
@@ -127,7 +127,7 @@ async function handleFederatedProfile(interaction, supabase, targetUser) {
.from("user_profiles")
.select("*")
.eq("id", link.user_id)
- .single();
+ .maybeSingle();
if (!profile) {
const embed = new EmbedBuilder()
diff --git a/aethex-bot/commands/rank.js b/aethex-bot/commands/rank.js
index 1f62e7a..ba7dab1 100644
--- a/aethex-bot/commands/rank.js
+++ b/aethex-bot/commands/rank.js
@@ -91,7 +91,7 @@ async function handleFederatedRank(interaction, supabase, target) {
.from('discord_links')
.select('user_id, primary_arm')
.eq('discord_id', target.id)
- .single();
+ .maybeSingle();
if (!link) {
return interaction.editReply({
@@ -107,7 +107,7 @@ async function handleFederatedRank(interaction, supabase, target) {
.from('user_profiles')
.select('username, avatar_url, xp, bio, prestige_level, total_xp_earned')
.eq('id', link.user_id)
- .single();
+ .maybeSingle();
const xp = profile?.xp || 0;
const prestige = profile?.prestige_level || 0;
diff --git a/aethex-bot/commands/set-realm.js b/aethex-bot/commands/set-realm.js
index 79f83c9..e583074 100644
--- a/aethex-bot/commands/set-realm.js
+++ b/aethex-bot/commands/set-realm.js
@@ -54,7 +54,7 @@ module.exports = {
.from("discord_links")
.select("user_id, primary_arm")
.eq("discord_id", interaction.user.id)
- .single();
+ .maybeSingle();
if (!link) {
const embed = new EmbedBuilder()
diff --git a/aethex-bot/commands/stats.js b/aethex-bot/commands/stats.js
index c764777..0d5bff0 100644
--- a/aethex-bot/commands/stats.js
+++ b/aethex-bot/commands/stats.js
@@ -16,7 +16,7 @@ module.exports = {
.from("discord_links")
.select("user_id, primary_arm, linked_at")
.eq("discord_id", interaction.user.id)
- .single();
+ .maybeSingle();
if (linkError) {
console.error("Stats link query error:", linkError);
@@ -37,7 +37,7 @@ module.exports = {
.from("user_profiles")
.select("*")
.eq("id", link.user_id)
- .single();
+ .maybeSingle();
const { count: postCount } = await supabase
.from("community_posts")
@@ -58,7 +58,7 @@ module.exports = {
.from("aethex_creators")
.select("verified, featured, total_projects")
.eq("user_id", link.user_id)
- .single();
+ .maybeSingle();
const armEmojis = {
labs: "🧪",
diff --git a/aethex-bot/commands/studio.js b/aethex-bot/commands/studio.js
index e046a21..a84c7c8 100644
--- a/aethex-bot/commands/studio.js
+++ b/aethex-bot/commands/studio.js
@@ -23,7 +23,7 @@ module.exports = {
.from('discord_links')
.select('user_id')
.eq('discord_id', target.id)
- .single();
+ .maybeSingle();
if (!link) {
return interaction.editReply({
@@ -39,7 +39,7 @@ module.exports = {
.from('user_profiles')
.select('username, avatar_url, bio')
.eq('id', link.user_id)
- .single();
+ .maybeSingle();
const { data: projects, count: projectCount } = await supabase
.from('studio_projects')
diff --git a/aethex-bot/commands/unlink.js b/aethex-bot/commands/unlink.js
index f179310..58d4ebf 100644
--- a/aethex-bot/commands/unlink.js
+++ b/aethex-bot/commands/unlink.js
@@ -16,7 +16,7 @@ module.exports = {
.from("discord_links")
.select("*")
.eq("discord_id", interaction.user.id)
- .single();
+ .maybeSingle();
if (!link) {
const embed = new EmbedBuilder()
diff --git a/aethex-bot/commands/userinfo.js b/aethex-bot/commands/userinfo.js
index d3234f7..56a31e8 100644
--- a/aethex-bot/commands/userinfo.js
+++ b/aethex-bot/commands/userinfo.js
@@ -51,14 +51,14 @@ module.exports = {
.from('discord_links')
.select('user_id, primary_arm, linked_at')
.eq('discord_id', target.id)
- .single();
+ .maybeSingle();
if (link) {
const { data: profile } = await supabase
.from('user_profiles')
.select('username, xp')
.eq('id', link.user_id)
- .single();
+ .maybeSingle();
embed.addFields(
{ name: 'AeThex Linked', value: 'Yes', inline: true },
diff --git a/aethex-bot/commands/verify-role.js b/aethex-bot/commands/verify-role.js
index f71d587..3b539fb 100644
--- a/aethex-bot/commands/verify-role.js
+++ b/aethex-bot/commands/verify-role.js
@@ -16,7 +16,7 @@ module.exports = {
.from("discord_links")
.select("user_id, primary_arm")
.eq("discord_id", interaction.user.id)
- .single();
+ .maybeSingle();
if (!link) {
const embed = new EmbedBuilder()
@@ -33,7 +33,7 @@ module.exports = {
.from("user_profiles")
.select("user_type")
.eq("id", link.user_id)
- .single();
+ .maybeSingle();
const { data: mappings } = await supabase
.from("discord_role_mappings")
diff --git a/aethex-bot/commands/verify.js b/aethex-bot/commands/verify.js
index 225869a..dc10ad5 100644
--- a/aethex-bot/commands/verify.js
+++ b/aethex-bot/commands/verify.js
@@ -23,7 +23,7 @@ module.exports = {
.from("discord_links")
.select("*")
.eq("discord_id", interaction.user.id)
- .single();
+ .maybeSingle();
if (existingLink) {
const embed = new EmbedBuilder()
diff --git a/aethex-bot/public/federation.html b/aethex-bot/public/federation.html
index f67d376..3a4a891 100644
--- a/aethex-bot/public/federation.html
+++ b/aethex-bot/public/federation.html
@@ -429,7 +429,7 @@
Features
Commands
Federation
- Dashboard
+ Pricing
Add to Server
diff --git a/aethex-bot/public/index.html b/aethex-bot/public/index.html
index d8b6365..a9e43f2 100644
--- a/aethex-bot/public/index.html
+++ b/aethex-bot/public/index.html
@@ -471,7 +471,8 @@
Home
Features
Commands
- Discord
+ Federation
+ Pricing