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
153 lines
4.6 KiB
JavaScript
153 lines
4.6 KiB
JavaScript
const { SlashCommandBuilder, EmbedBuilder } = require("discord.js");
|
|
|
|
module.exports = {
|
|
data: new SlashCommandBuilder()
|
|
.setName("stats")
|
|
.setDescription("View your AeThex statistics and activity"),
|
|
|
|
async execute(interaction, supabase) {
|
|
if (!supabase) {
|
|
return interaction.reply({ content: "This feature requires Supabase to be configured.", ephemeral: true });
|
|
}
|
|
await interaction.deferReply({ ephemeral: true });
|
|
|
|
try {
|
|
const { data: link, error: linkError } = await supabase
|
|
.from("discord_links")
|
|
.select("user_id, primary_arm, linked_at")
|
|
.eq("discord_id", interaction.user.id)
|
|
.maybeSingle();
|
|
|
|
if (linkError) {
|
|
console.error("Stats link query error:", linkError);
|
|
}
|
|
|
|
if (!link) {
|
|
const embed = new EmbedBuilder()
|
|
.setColor(0xff6b6b)
|
|
.setTitle("❌ Not Linked")
|
|
.setDescription(
|
|
"You must link your Discord account to AeThex first.\nUse `/verify` to get started."
|
|
);
|
|
|
|
return await interaction.editReply({ embeds: [embed] });
|
|
}
|
|
|
|
const { data: profile } = await supabase
|
|
.from("user_profiles")
|
|
.select("*")
|
|
.eq("id", link.user_id)
|
|
.maybeSingle();
|
|
|
|
const { count: postCount } = await supabase
|
|
.from("community_posts")
|
|
.select("*", { count: "exact", head: true })
|
|
.eq("user_id", link.user_id);
|
|
|
|
const { count: likeCount } = await supabase
|
|
.from("community_likes")
|
|
.select("*", { count: "exact", head: true })
|
|
.eq("user_id", link.user_id);
|
|
|
|
const { count: commentCount } = await supabase
|
|
.from("community_comments")
|
|
.select("*", { count: "exact", head: true })
|
|
.eq("user_id", link.user_id);
|
|
|
|
const { data: creatorProfile } = await supabase
|
|
.from("aethex_creators")
|
|
.select("verified, featured, total_projects")
|
|
.eq("user_id", link.user_id)
|
|
.maybeSingle();
|
|
|
|
const armEmojis = {
|
|
labs: "🧪",
|
|
gameforge: "🎮",
|
|
corp: "💼",
|
|
foundation: "🤝",
|
|
devlink: "💻",
|
|
};
|
|
|
|
const linkedDate = new Date(link.linked_at);
|
|
const daysSinceLinked = Math.floor(
|
|
(Date.now() - linkedDate.getTime()) / (1000 * 60 * 60 * 24)
|
|
);
|
|
|
|
// Validate avatar URL - must be http/https, not base64
|
|
let avatarUrl = interaction.user.displayAvatarURL();
|
|
if (profile?.avatar_url && profile.avatar_url.startsWith('http')) {
|
|
avatarUrl = profile.avatar_url;
|
|
}
|
|
|
|
const embed = new EmbedBuilder()
|
|
.setColor(0x7289da)
|
|
.setTitle(`📊 ${profile?.full_name || interaction.user.username}'s Stats`)
|
|
.setThumbnail(avatarUrl)
|
|
.addFields(
|
|
{
|
|
name: `${armEmojis[link.primary_arm] || "⚔️"} Primary Realm`,
|
|
value: link.primary_arm || "Not set",
|
|
inline: true,
|
|
},
|
|
{
|
|
name: "👤 Account Type",
|
|
value: profile?.user_type || "community_member",
|
|
inline: true,
|
|
},
|
|
{
|
|
name: "📅 Days Linked",
|
|
value: `${daysSinceLinked} days`,
|
|
inline: true,
|
|
}
|
|
)
|
|
.addFields(
|
|
{
|
|
name: "📝 Posts",
|
|
value: `${postCount || 0}`,
|
|
inline: true,
|
|
},
|
|
{
|
|
name: "❤️ Likes Given",
|
|
value: `${likeCount || 0}`,
|
|
inline: true,
|
|
},
|
|
{
|
|
name: "💬 Comments",
|
|
value: `${commentCount || 0}`,
|
|
inline: true,
|
|
}
|
|
);
|
|
|
|
if (creatorProfile) {
|
|
embed.addFields({
|
|
name: "🎨 Creator Status",
|
|
value: [
|
|
creatorProfile.verified ? "✅ Verified Creator" : "⏳ Pending Verification",
|
|
creatorProfile.featured ? "⭐ Featured" : "",
|
|
`📁 ${creatorProfile.total_projects || 0} Projects`,
|
|
]
|
|
.filter(Boolean)
|
|
.join("\n"),
|
|
});
|
|
}
|
|
|
|
embed
|
|
.addFields({
|
|
name: "🔗 Full Profile",
|
|
value: `[View on AeThex](https://aethex.dev/creators/${profile?.username || link.user_id})`,
|
|
})
|
|
.setFooter({ text: "AeThex | Your Creative Hub" })
|
|
.setTimestamp();
|
|
|
|
await interaction.editReply({ embeds: [embed] });
|
|
} catch (error) {
|
|
console.error("Stats command error:", error);
|
|
const embed = new EmbedBuilder()
|
|
.setColor(0xff0000)
|
|
.setTitle("❌ Error")
|
|
.setDescription("Failed to fetch stats. Please try again.");
|
|
|
|
await interaction.editReply({ embeds: [embed] });
|
|
}
|
|
},
|
|
};
|