diff --git a/api/community/collaboration-posts.ts b/api/community/collaboration-posts.ts index 9b56b381..535a4e1b 100644 --- a/api/community/collaboration-posts.ts +++ b/api/community/collaboration-posts.ts @@ -13,18 +13,34 @@ if (!supabaseUrl || !supabaseServiceRole) { const supabase = createClient(supabaseUrl, supabaseServiceRole); -const VALID_ARMS = ["labs", "gameforge", "corp", "foundation", "devlink", "nexus", "staff"]; +const VALID_ARMS = [ + "labs", + "gameforge", + "corp", + "foundation", + "devlink", + "nexus", + "staff", +]; export default async function handler(req: any, res: any) { if (req.method === "POST") { try { - const { title, content, arm_affiliation, creator_id, collaborator_ids, tags, category } = - req.body; + const { + title, + content, + arm_affiliation, + creator_id, + collaborator_ids, + tags, + category, + } = req.body; // Validate required fields if (!title || !content || !arm_affiliation || !creator_id) { return res.status(400).json({ - error: "Missing required fields: title, content, arm_affiliation, creator_id", + error: + "Missing required fields: title, content, arm_affiliation, creator_id", }); } @@ -93,7 +109,11 @@ export default async function handler(req: any, res: any) { }); // Add collaborators if provided - if (collaborator_ids && Array.isArray(collaborator_ids) && collaborator_ids.length > 0) { + if ( + collaborator_ids && + Array.isArray(collaborator_ids) && + collaborator_ids.length > 0 + ) { const collaboratorInserts = collaborator_ids .filter((id: string) => id !== creator_id) // Exclude creator from collaborators .map((id: string) => ({ @@ -103,7 +123,9 @@ export default async function handler(req: any, res: any) { })); if (collaboratorInserts.length > 0) { - await supabase.from("collaboration_posts_authors").insert(collaboratorInserts); + await supabase + .from("collaboration_posts_authors") + .insert(collaboratorInserts); } } @@ -140,7 +162,7 @@ export default async function handler(req: any, res: any) { avatar_url ) ) - ` + `, ) .eq("id", postId) .single(); @@ -199,7 +221,7 @@ export default async function handler(req: any, res: any) { ) ) `, - { count: "exact" } + { count: "exact" }, ) .eq("is_published", true) .order("created_at", { ascending: false }); @@ -211,7 +233,10 @@ export default async function handler(req: any, res: any) { } // Apply pagination - query = query.range(parseInt(offset), parseInt(offset) + parseInt(limit) - 1); + query = query.range( + parseInt(offset), + parseInt(offset) + parseInt(limit) - 1, + ); const { data, error, count } = await query; @@ -236,7 +261,8 @@ export default async function handler(req: any, res: any) { if (req.method === "PUT") { try { - const { id, title, content, arm_affiliation, category, tags, user_id } = req.body; + const { id, title, content, arm_affiliation, category, tags, user_id } = + req.body; if (!id || !user_id) { return res.status(400).json({ error: "Missing id or user_id" }); @@ -274,11 +300,9 @@ export default async function handler(req: any, res: any) { } if (arm_affiliation && !VALID_ARMS.includes(arm_affiliation)) { - return res - .status(400) - .json({ - error: `Invalid arm_affiliation. Must be one of: ${VALID_ARMS.join(", ")}`, - }); + return res.status(400).json({ + error: `Invalid arm_affiliation. Must be one of: ${VALID_ARMS.join(", ")}`, + }); } // Build update object @@ -323,7 +347,7 @@ export default async function handler(req: any, res: any) { avatar_url ) ) - ` + `, ); if (error) { @@ -384,7 +408,10 @@ export default async function handler(req: any, res: any) { message: "Post deleted successfully", }); } catch (error: any) { - console.error("[Collaboration Posts API DELETE] Unexpected error:", error); + console.error( + "[Collaboration Posts API DELETE] Unexpected error:", + error, + ); return res .status(500) .json({ error: error.message || "Internal server error" }); diff --git a/api/community/notifications.ts b/api/community/notifications.ts index f7fe609a..452c4831 100644 --- a/api/community/notifications.ts +++ b/api/community/notifications.ts @@ -44,7 +44,7 @@ export default async function handler(req: any, res: any) { avatar_url ) `, - { count: "exact" } + { count: "exact" }, ) .eq("user_id", user_id); @@ -93,7 +93,8 @@ export default async function handler(req: any, res: any) { if (!user_id || !actor_id || !notification_type || !title) { return res.status(400).json({ - error: "Missing required fields: user_id, actor_id, notification_type, title", + error: + "Missing required fields: user_id, actor_id, notification_type, title", }); } @@ -141,7 +142,7 @@ export default async function handler(req: any, res: any) { full_name, avatar_url ) - ` + `, ); if (error) { @@ -208,7 +209,7 @@ export default async function handler(req: any, res: any) { full_name, avatar_url ) - ` + `, ); if (error) { diff --git a/api/community/post-comments.ts b/api/community/post-comments.ts index 065d54f2..e2a5c957 100644 --- a/api/community/post-comments.ts +++ b/api/community/post-comments.ts @@ -38,7 +38,7 @@ export default async function handler(req: any, res: any) { avatar_url ) `, - { count: "exact" } + { count: "exact" }, ) .eq("post_id", post_id) .order("created_at", { ascending: false }) @@ -74,7 +74,9 @@ export default async function handler(req: any, res: any) { } if (content.trim().length === 0) { - return res.status(400).json({ error: "Comment content cannot be empty" }); + return res + .status(400) + .json({ error: "Comment content cannot be empty" }); } if (content.length > 1000) { @@ -103,7 +105,7 @@ export default async function handler(req: any, res: any) { full_name, avatar_url ) - ` + `, ); if (error) { @@ -139,9 +141,7 @@ export default async function handler(req: any, res: any) { const { comment_id, user_id } = req.body; if (!comment_id || !user_id) { - return res - .status(400) - .json({ error: "Missing comment_id or user_id" }); + return res.status(400).json({ error: "Missing comment_id or user_id" }); } // Get comment to verify ownership @@ -153,9 +153,7 @@ export default async function handler(req: any, res: any) { if (fetchError) { console.error("[Comments API] Fetch error:", fetchError); - return res - .status(404) - .json({ error: "Comment not found" }); + return res.status(404).json({ error: "Comment not found" }); } if (comment.user_id !== user_id) { diff --git a/api/community/post-likes.ts b/api/community/post-likes.ts index 64b75540..3755d35f 100644 --- a/api/community/post-likes.ts +++ b/api/community/post-likes.ts @@ -19,9 +19,7 @@ export default async function handler(req: any, res: any) { const { post_id, user_id } = req.body; if (!post_id || !user_id) { - return res - .status(400) - .json({ error: "Missing post_id or user_id" }); + return res.status(400).json({ error: "Missing post_id or user_id" }); } // Check if user has already liked this post diff --git a/api/community/posts.ts b/api/community/posts.ts index a62534d5..7c061445 100644 --- a/api/community/posts.ts +++ b/api/community/posts.ts @@ -13,17 +13,27 @@ if (!supabaseUrl || !supabaseServiceRole) { const supabase = createClient(supabaseUrl, supabaseServiceRole); -const VALID_ARMS = ["labs", "gameforge", "corp", "foundation", "devlink", "nexus", "staff"]; +const VALID_ARMS = [ + "labs", + "gameforge", + "corp", + "foundation", + "devlink", + "nexus", + "staff", +]; export default async function handler(req: any, res: any) { if (req.method === "POST") { try { - const { title, content, arm_affiliation, author_id, tags, category } = req.body; + const { title, content, arm_affiliation, author_id, tags, category } = + req.body; // Validate required fields if (!title || !content || !arm_affiliation || !author_id) { return res.status(400).json({ - error: "Missing required fields: title, content, arm_affiliation, author_id", + error: + "Missing required fields: title, content, arm_affiliation, author_id", }); } @@ -92,7 +102,7 @@ export default async function handler(req: any, res: any) { full_name, avatar_url ) - ` + `, ); if (error) { @@ -118,7 +128,9 @@ export default async function handler(req: any, res: any) { title: title.substring(0, 100), }, }), - }).catch((err) => console.error("[Posts API] Activity publish error:", err)); + }).catch((err) => + console.error("[Posts API] Activity publish error:", err), + ); } catch (error) { console.error("[Posts API] Failed to publish activity:", error); } @@ -134,7 +146,9 @@ export default async function handler(req: any, res: any) { action: "post_created", amount: 25, }), - }).catch((err) => console.error("[Posts API] Rewards apply error:", err)); + }).catch((err) => + console.error("[Posts API] Rewards apply error:", err), + ); } catch (error) { console.error("[Posts API] Failed to apply rewards:", error); } @@ -152,7 +166,8 @@ export default async function handler(req: any, res: any) { if (req.method === "PUT") { try { - const { id, title, content, arm_affiliation, category, tags, user_id } = req.body; + const { id, title, content, arm_affiliation, category, tags, user_id } = + req.body; if (!id || !user_id) { return res.status(400).json({ error: "Missing id or user_id" }); @@ -190,11 +205,9 @@ export default async function handler(req: any, res: any) { } if (arm_affiliation && !VALID_ARMS.includes(arm_affiliation)) { - return res - .status(400) - .json({ - error: `Invalid arm_affiliation. Must be one of: ${VALID_ARMS.join(", ")}`, - }); + return res.status(400).json({ + error: `Invalid arm_affiliation. Must be one of: ${VALID_ARMS.join(", ")}`, + }); } // Build update object @@ -229,7 +242,7 @@ export default async function handler(req: any, res: any) { full_name, avatar_url ) - ` + `, ); if (error) { diff --git a/api/discord/send-community-post.ts b/api/discord/send-community-post.ts index e39d3f0f..fa3d9117 100644 --- a/api/discord/send-community-post.ts +++ b/api/discord/send-community-post.ts @@ -51,11 +51,20 @@ export default async function handler(req: any, res: any) { } try { - const { post_id, title, content, arm_affiliation, author_id, tags, category } = req.body; + const { + post_id, + title, + content, + arm_affiliation, + author_id, + tags, + category, + } = req.body; if (!post_id || !title || !content || !arm_affiliation || !author_id) { return res.status(400).json({ - error: "Missing required fields: post_id, title, content, arm_affiliation, author_id", + error: + "Missing required fields: post_id, title, content, arm_affiliation, author_id", }); } @@ -94,7 +103,8 @@ export default async function handler(req: any, res: any) { } // Build Discord embed - const contentPreview = content.substring(0, 500) + (content.length > 500 ? "..." : ""); + const contentPreview = + content.substring(0, 500) + (content.length > 500 ? "..." : ""); const color = ARM_COLORS[arm_affiliation] || 0x6366f1; const embedPayload: WebhookPayload = { @@ -152,7 +162,7 @@ export default async function handler(req: any, res: any) { console.error( `[Discord Post API] Webhook failed:`, response.status, - error + error, ); throw new Error(`Discord webhook error: ${response.status}`); } @@ -161,7 +171,7 @@ export default async function handler(req: any, res: any) { } catch (error: any) { console.error( `[Discord Post API] Error sending to webhook:`, - error.message + error.message, ); return { success: false, @@ -169,10 +179,12 @@ export default async function handler(req: any, res: any) { error: error.message, }; } - }) + }), ); - const successful = webhookResults.filter((r) => r.status === "fulfilled" && r.value.success).length; + const successful = webhookResults.filter( + (r) => r.status === "fulfilled" && r.value.success, + ).length; return res.status(200).json({ success: true, diff --git a/api/discord/webhooks.ts b/api/discord/webhooks.ts index b4a9c69d..ecaf036d 100644 --- a/api/discord/webhooks.ts +++ b/api/discord/webhooks.ts @@ -24,7 +24,9 @@ export default async function handler(req: any, res: any) { const { data, error } = await supabase .from("discord_post_webhooks") - .select("id, guild_id, channel_id, webhook_id, arm_affiliation, auto_post, created_at") + .select( + "id, guild_id, channel_id, webhook_id, arm_affiliation, auto_post, created_at", + ) .eq("user_id", user_id) .order("created_at", { ascending: false }); @@ -46,17 +48,40 @@ export default async function handler(req: any, res: any) { if (req.method === "POST") { try { - const { user_id, guild_id, channel_id, webhook_url, webhook_id, arm_affiliation, auto_post } = - req.body; + const { + user_id, + guild_id, + channel_id, + webhook_url, + webhook_id, + arm_affiliation, + auto_post, + } = req.body; - if (!user_id || !guild_id || !channel_id || !webhook_url || !webhook_id || !arm_affiliation) { + if ( + !user_id || + !guild_id || + !channel_id || + !webhook_url || + !webhook_id || + !arm_affiliation + ) { return res.status(400).json({ - error: "Missing required fields: user_id, guild_id, channel_id, webhook_url, webhook_id, arm_affiliation", + error: + "Missing required fields: user_id, guild_id, channel_id, webhook_url, webhook_id, arm_affiliation", }); } // Validate arm_affiliation - const validArms = ["labs", "gameforge", "corp", "foundation", "devlink", "nexus", "staff"]; + const validArms = [ + "labs", + "gameforge", + "corp", + "foundation", + "devlink", + "nexus", + "staff", + ]; if (!validArms.includes(arm_affiliation)) { return res.status(400).json({ error: `Invalid arm_affiliation. Must be one of: ${validArms.join(", ")}`, @@ -67,7 +92,8 @@ export default async function handler(req: any, res: any) { try { const testPayload = { username: "AeThex Community Feed", - content: "✅ Webhook successfully configured for AeThex Community Posts!", + content: + "✅ Webhook successfully configured for AeThex Community Posts!", }; const testResponse = await fetch(webhook_url, { @@ -101,7 +127,9 @@ export default async function handler(req: any, res: any) { arm_affiliation, auto_post: auto_post !== false, // Default to true }) - .select("id, guild_id, channel_id, webhook_id, arm_affiliation, auto_post, created_at"); + .select( + "id, guild_id, channel_id, webhook_id, arm_affiliation, auto_post, created_at", + ); if (error) { console.error("[Webhooks API] Insert error:", error); @@ -154,7 +182,9 @@ export default async function handler(req: any, res: any) { .from("discord_post_webhooks") .update({ auto_post }) .eq("id", id) - .select("id, guild_id, channel_id, webhook_id, arm_affiliation, auto_post, created_at"); + .select( + "id, guild_id, channel_id, webhook_id, arm_affiliation, auto_post, created_at", + ); if (error) { console.error("[Webhooks API] Update error:", error); diff --git a/client/components/feed/ArmPostCard.tsx b/client/components/feed/ArmPostCard.tsx index cad8bd5d..204f6dae 100644 --- a/client/components/feed/ArmPostCard.tsx +++ b/client/components/feed/ArmPostCard.tsx @@ -3,7 +3,14 @@ import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Heart, MessageCircle, Share2 } from "lucide-react"; -export type ArmType = "labs" | "gameforge" | "corp" | "foundation" | "devlink" | "nexus" | "staff"; +export type ArmType = + | "labs" + | "gameforge" + | "corp" + | "foundation" + | "devlink" + | "nexus" + | "staff"; const ARM_CONFIG: Record = { labs: { @@ -120,7 +127,9 @@ export default function ArmPostCard({ [ {config.label} ] - {post.title} + + {post.title} + diff --git a/client/components/feed/CommentsModal.tsx b/client/components/feed/CommentsModal.tsx index 4863029a..f604747f 100644 --- a/client/components/feed/CommentsModal.tsx +++ b/client/components/feed/CommentsModal.tsx @@ -59,7 +59,7 @@ export default function CommentsModal({ setIsLoading(true); try { const response = await fetch( - `${API_BASE}/api/community/post-comments?post_id=${postId}&limit=50` + `${API_BASE}/api/community/post-comments?post_id=${postId}&limit=50`, ); if (response.ok) { const data = await response.json(); @@ -144,23 +144,20 @@ export default function CommentsModal({ const handleDeleteComment = async (commentId: string) => { setIsSubmitting(true); try { - const response = await fetch( - `${API_BASE}/api/community/post-comments`, - { - method: "DELETE", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - comment_id: commentId, - user_id: currentUserId, - }), - } - ); + const response = await fetch(`${API_BASE}/api/community/post-comments`, { + method: "DELETE", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + comment_id: commentId, + user_id: currentUserId, + }), + }); if (response.ok) { setComments((prev) => - prev.filter((comment) => comment.id !== commentId) + prev.filter((comment) => comment.id !== commentId), ); aethexToast.success({ title: "Comment deleted", diff --git a/client/components/feed/PostComposer.tsx b/client/components/feed/PostComposer.tsx index 2cd6cdc6..982ed0f8 100644 --- a/client/components/feed/PostComposer.tsx +++ b/client/components/feed/PostComposer.tsx @@ -221,7 +221,9 @@ export default function PostComposer({ } else { const error = await response.json(); aethexToast.error({ - title: editingPost ? "Failed to update post" : "Failed to create post", + title: editingPost + ? "Failed to update post" + : "Failed to create post", description: error.error || "Please try again", }); } @@ -301,7 +303,10 @@ export default function PostComposer({ - setArmAffiliation(value as ArmType)} + > @@ -376,7 +381,9 @@ export default function PostComposer({ disabled={isSubmitting || !title.trim() || !content.trim()} className="w-full bg-gradient-to-r from-aethex-600 to-neon-blue hover:from-aethex-700 hover:to-neon-blue/90 text-white font-semibold" > - {isSubmitting && } + {isSubmitting && ( + + )} {editingPost ? "Update Post" : "Publish Post"}