From df2b52af715921e6e9a735f74bb518fc32fddd6a Mon Sep 17 00:00:00 2001 From: "Builder.io" Date: Sat, 18 Oct 2025 03:49:38 +0000 Subject: [PATCH] Prettier format pending files --- client/App.tsx | 5 +- client/lib/aethex-collab-service.ts | 55 ++++++++++--- client/lib/aethex-social-service.ts | 16 +++- client/pages/Dashboard.tsx | 105 +++++++++++++++++++++---- client/pages/Privacy.tsx | 99 ++++++++++++++++------- client/pages/ProjectBoard.tsx | 101 +++++++++++++++++++----- client/pages/Teams.tsx | 108 ++++++++++++++++++++----- client/pages/Terms.tsx | 73 ++++++++++------- server/index.ts | 117 ++++++++++++++++++++++------ 9 files changed, 531 insertions(+), 148 deletions(-) diff --git a/client/App.tsx b/client/App.tsx index 3337426c..d209dfe2 100644 --- a/client/App.tsx +++ b/client/App.tsx @@ -74,7 +74,10 @@ const App = () => ( } /> } /> } /> - } /> + } + /> } /> } /> diff --git a/client/lib/aethex-collab-service.ts b/client/lib/aethex-collab-service.ts index e359a50b..5e08ca5a 100644 --- a/client/lib/aethex-collab-service.ts +++ b/client/lib/aethex-collab-service.ts @@ -1,5 +1,8 @@ import { supabase } from "@/lib/supabase"; -import { aethexUserService, aethexNotificationService } from "@/lib/aethex-database-adapter"; +import { + aethexUserService, + aethexNotificationService, +} from "@/lib/aethex-database-adapter"; export type TeamVisibility = "public" | "private"; export type MembershipRole = "owner" | "admin" | "member"; @@ -11,14 +14,21 @@ export const aethexCollabService = { async listMyTeams(userId: string) { const { data, error } = await supabase .from("team_memberships") - .select("team_id, teams:team_id ( id, name, slug, description, visibility, created_at )") + .select( + "team_id, teams:team_id ( id, name, slug, description, visibility, created_at )", + ) .eq("user_id", userId) .order("created_at", { ascending: false }); if (error) return [] as any[]; return (data || []) as any[]; }, - async createTeam(ownerId: string, name: string, description?: string | null, visibility: TeamVisibility = "private") { + async createTeam( + ownerId: string, + name: string, + description?: string | null, + visibility: TeamVisibility = "private", + ) { // Ensure the owner has a user_profiles row to satisfy FK try { await aethexUserService.getCurrentUser(); @@ -26,7 +36,12 @@ export const aethexCollabService = { const { data, error } = await supabase .from("teams") - .insert({ owner_id: ownerId, name, description: description || null, visibility }) + .insert({ + owner_id: ownerId, + name, + description: description || null, + visibility, + }) .select() .single(); if (error) throw new Error(error.message || "Unable to create team"); @@ -52,7 +67,11 @@ export const aethexCollabService = { return team; }, - async addTeamMember(teamId: string, userId: string, role: MembershipRole = "member") { + async addTeamMember( + teamId: string, + userId: string, + role: MembershipRole = "member", + ) { const { error } = await supabase .from("team_memberships") .insert({ team_id: teamId, user_id: userId, role }); @@ -60,7 +79,11 @@ export const aethexCollabService = { }, // Projects - async addProjectMember(projectId: string, userId: string, role: ProjectRole = "contributor") { + async addProjectMember( + projectId: string, + userId: string, + role: ProjectRole = "contributor", + ) { const { error } = await supabase .from("project_members") .insert({ project_id: projectId, user_id: userId, role }); @@ -70,7 +93,9 @@ export const aethexCollabService = { async listProjectMembers(projectId: string) { const { data, error } = await supabase .from("project_members") - .select("user_id, role, user:user_id ( id, full_name, username, avatar_url )") + .select( + "user_id, role, user:user_id ( id, full_name, username, avatar_url )", + ) .eq("project_id", projectId); if (error) return [] as any[]; return (data || []) as any[]; @@ -87,10 +112,22 @@ export const aethexCollabService = { return (data || []) as any[]; }, - async createTask(projectId: string, title: string, description?: string | null, assigneeId?: string | null, dueDate?: string | null) { + async createTask( + projectId: string, + title: string, + description?: string | null, + assigneeId?: string | null, + dueDate?: string | null, + ) { const { data, error } = await supabase .from("project_tasks") - .insert({ project_id: projectId, title, description: description || null, assignee_id: assigneeId || null, due_date: dueDate || null }) + .insert({ + project_id: projectId, + title, + description: description || null, + assignee_id: assigneeId || null, + due_date: dueDate || null, + }) .select() .single(); if (error) throw new Error(error.message || "Unable to create task"); diff --git a/client/lib/aethex-social-service.ts b/client/lib/aethex-social-service.ts index 9201e197..8ce35ff6 100644 --- a/client/lib/aethex-social-service.ts +++ b/client/lib/aethex-social-service.ts @@ -56,7 +56,10 @@ export const aethexSocialService = { const resp = await fetch("/api/social/follow", { method: "POST", headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ follower_id: followerId, following_id: followingId }), + body: JSON.stringify({ + follower_id: followerId, + following_id: followingId, + }), }); if (!resp.ok) throw new Error(await resp.text()); }, @@ -65,7 +68,10 @@ export const aethexSocialService = { const resp = await fetch("/api/social/unfollow", { method: "POST", headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ follower_id: followerId, following_id: followingId }), + body: JSON.stringify({ + follower_id: followerId, + following_id: followingId, + }), }); if (!resp.ok) throw new Error(await resp.text()); }, @@ -148,7 +154,11 @@ export const aethexSocialService = { const resp = await fetch("/api/social/endorse", { method: "POST", headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ endorser_id: endorserId, endorsed_id: endorsedId, skill }), + body: JSON.stringify({ + endorser_id: endorserId, + endorsed_id: endorsedId, + skill, + }), }); if (!resp.ok) throw new Error(await resp.text()); }, diff --git a/client/pages/Dashboard.tsx b/client/pages/Dashboard.tsx index bb01787d..3bd0b64c 100644 --- a/client/pages/Dashboard.tsx +++ b/client/pages/Dashboard.tsx @@ -509,10 +509,30 @@ export default function Dashboard() { const showProfileSetup = !profileComplete; const statsDisplay = [ - { label: "Active Projects", value: stats.activeProjects, icon: Rocket, color: "from-blue-500 to-purple-600" }, - { label: "Completed Tasks", value: stats.completedTasks, icon: Trophy, color: "from-green-500 to-blue-600" }, - { label: "Team Members", value: stats.teamMembers, icon: Users, color: "from-purple-500 to-pink-600" }, - { label: "Performance Score", value: stats.performanceScore, icon: TrendingUp, color: "from-orange-500 to-red-600" }, + { + label: "Active Projects", + value: stats.activeProjects, + icon: Rocket, + color: "from-blue-500 to-purple-600", + }, + { + label: "Completed Tasks", + value: stats.completedTasks, + icon: Trophy, + color: "from-green-500 to-blue-600", + }, + { + label: "Team Members", + value: stats.teamMembers, + icon: Users, + color: "from-purple-500 to-pink-600", + }, + { + label: "Performance Score", + value: stats.performanceScore, + icon: TrendingUp, + color: "from-orange-500 to-red-600", + }, ]; const getProgressPercentage = (project: any) => { @@ -561,10 +581,18 @@ export default function Dashboard() { }; const quickActions = [ - { title: "Start New Project", icon: Rocket, color: "from-blue-500 to-purple-600" }, + { + title: "Start New Project", + icon: Rocket, + color: "from-blue-500 to-purple-600", + }, { title: "Create Team", icon: Users, color: "from-green-500 to-blue-600" }, { title: "Access Labs", icon: Zap, color: "from-yellow-500 to-orange-600" }, - { title: "View Analytics", icon: BarChart3, color: "from-purple-500 to-pink-600" }, + { + title: "View Analytics", + icon: BarChart3, + color: "from-purple-500 to-pink-600", + }, ]; if (isLoading) { @@ -1200,7 +1228,12 @@ export default function Dashboard() { Your active development projects - @@ -1266,7 +1299,13 @@ export default function Dashboard() { > {getPriorityFromTech(project.technologies || [])} - @@ -1406,14 +1445,27 @@ export default function Dashboard() { {teams.length === 0 ? ( -
No teams yet.
+
+ No teams yet. +
) : ( teams.slice(0, 6).map((t: any) => { const team = (t as any).teams || t; return ( -
-
{team.name}
- +
+
+ {team.name} +
+
); }) @@ -1428,15 +1480,34 @@ export default function Dashboard() { {invites.length === 0 ? ( -
No invites yet.
+
+ No invites yet. +
) : ( invites.slice(0, 6).map((inv: any) => ( -
+
-
{inv.invitee_email}
-
{inv.status}
+
+ {inv.invitee_email} +
+
+ {inv.status} +
- +
)) )} diff --git a/client/pages/Privacy.tsx b/client/pages/Privacy.tsx index bd8cb9c3..32246f8a 100644 --- a/client/pages/Privacy.tsx +++ b/client/pages/Privacy.tsx @@ -6,39 +6,68 @@ export default function Privacy() {
-

Privacy Policy

-

Effective date: 2025-10-18

+

+ Privacy Policy +

- This Privacy Policy explains how AeThex ("we", "us") collects, uses, shares, and protects - information when you use our products, sites, and services (the "Services"). + Effective date: 2025-10-18 +

+

+ This Privacy Policy explains how AeThex ("we", "us") collects, + uses, shares, and protects information when you use our products, + sites, and services (the "Services").

Information We Collect

    -
  • Account data: name, username, email, profile details, social links.
  • -
  • Content: posts, comments, projects, teams, endorsements, activity metadata.
  • -
  • Usage data: device/browser information, pages visited, interactions, approximate location.
  • -
  • Cookies & similar: session and preference cookies for authentication and settings.
  • +
  • + Account data: name, username, email, profile details, social + links. +
  • +
  • + Content: posts, comments, projects, teams, endorsements, + activity metadata. +
  • +
  • + Usage data: device/browser information, pages visited, + interactions, approximate location. +
  • +
  • + Cookies & similar: session and preference cookies for + authentication and settings. +

How We Use Information

    -
  • Provide and improve the Services, including social, projects, teams, and notifications.
  • -
  • Security, abuse prevention, fraud detection, and diagnostics.
  • -
  • Personalization (e.g., recommendations, feed ranking) and aggregated analytics.
  • -
  • Communications: transactional emails (verification, invites, alerts) and product updates.
  • +
  • + Provide and improve the Services, including social, projects, + teams, and notifications. +
  • +
  • + Security, abuse prevention, fraud detection, and diagnostics. +
  • +
  • + Personalization (e.g., recommendations, feed ranking) and + aggregated analytics. +
  • +
  • + Communications: transactional emails (verification, invites, + alerts) and product updates. +

Legal Bases (EEA/UK)

- We process data under: (i) Performance of a contract (providing core features), (ii) Legitimate - interests (security, analytics, product improvement), (iii) Consent (where required), and (iv) + We process data under: (i) Performance of a contract (providing + core features), (ii) Legitimate interests (security, analytics, + product improvement), (iii) Consent (where required), and (iv) Compliance with legal obligations.

@@ -46,8 +75,9 @@ export default function Privacy() {

Sharing & Service Providers

- We do not sell your personal information. We use trusted sub-processors to operate the platform: - Supabase (auth, database, storage), Vercel/Netlify (hosting/CDN), and Resend (email). These + We do not sell your personal information. We use trusted + sub-processors to operate the platform: Supabase (auth, database, + storage), Vercel/Netlify (hosting/CDN), and Resend (email). These providers process data on our behalf under appropriate agreements.

@@ -55,24 +85,31 @@ export default function Privacy() {

International Transfers

- Data may be processed in the United States and other countries. Where applicable, we rely on - appropriate safeguards (e.g., SCCs) for cross-border transfers. + Data may be processed in the United States and other countries. + Where applicable, we rely on appropriate safeguards (e.g., SCCs) + for cross-border transfers.

Data Retention

- We retain data for as long as needed to provide Services, comply with law, resolve disputes, - and enforce agreements. You may request deletion of your account data, subject to legal holds. + We retain data for as long as needed to provide Services, comply + with law, resolve disputes, and enforce agreements. You may + request deletion of your account data, subject to legal holds.

Your Rights

    -
  • Access, correction, deletion, and portability of your data.
  • -
  • Object to or restrict certain processing; withdraw consent where applicable.
  • +
  • + Access, correction, deletion, and portability of your data. +
  • +
  • + Object to or restrict certain processing; withdraw consent where + applicable. +
  • Manage notifications and email preferences in-app.
@@ -80,31 +117,35 @@ export default function Privacy() {

Security

- We use industry-standard measures to protect data in transit and at rest. No method of - transmission or storage is 100% secure; you are responsible for safeguarding credentials. + We use industry-standard measures to protect data in transit and + at rest. No method of transmission or storage is 100% secure; you + are responsible for safeguarding credentials.

Children

- Our Services are not directed to children under 13 (or as defined by local law). We do not - knowingly collect data from children. If you believe a child has provided data, contact us. + Our Services are not directed to children under 13 (or as defined + by local law). We do not knowingly collect data from children. If + you believe a child has provided data, contact us.

Changes

- We may update this Policy. Material changes will be announced via the app or email. Your - continued use after changes constitutes acceptance. + We may update this Policy. Material changes will be announced via + the app or email. Your continued use after changes constitutes + acceptance.

Contact

- For privacy inquiries: privacy@aethex.biz. For support: support@aethex.biz. + For privacy inquiries: privacy@aethex.biz. For support: + support@aethex.biz.

diff --git a/client/pages/ProjectBoard.tsx b/client/pages/ProjectBoard.tsx index 085b7c9d..dd96d08e 100644 --- a/client/pages/ProjectBoard.tsx +++ b/client/pages/ProjectBoard.tsx @@ -2,7 +2,13 @@ import Layout from "@/components/Layout"; import { useAuth } from "@/contexts/AuthContext"; import { useEffect, useMemo, useState } from "react"; import { useNavigate, useParams } from "react-router-dom"; -import { Card, CardHeader, CardTitle, CardDescription, CardContent } from "@/components/ui/card"; +import { + Card, + CardHeader, + CardTitle, + CardDescription, + CardContent, +} from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Textarea } from "@/components/ui/textarea"; @@ -10,7 +16,11 @@ import { Badge } from "@/components/ui/badge"; import { aethexCollabService } from "@/lib/aethex-collab-service"; import LoadingScreen from "@/components/LoadingScreen"; -const columns: { key: "todo"|"doing"|"done"|"blocked"; title: string; hint: string }[] = [ +const columns: { + key: "todo" | "doing" | "done" | "blocked"; + title: string; + hint: string; +}[] = [ { key: "todo", title: "To do", hint: "Planned" }, { key: "doing", title: "In progress", hint: "Active" }, { key: "done", title: "Done", hint: "Completed" }, @@ -47,7 +57,12 @@ export default function ProjectBoard() { }, [projectId]); const grouped = useMemo(() => { - const map: Record = { todo: [], doing: [], done: [], blocked: [] }; + const map: Record = { + todo: [], + doing: [], + done: [], + blocked: [], + }; for (const t of tasks) { map[t.status || "todo"].push(t); } @@ -59,7 +74,13 @@ export default function ProjectBoard() { if (!title.trim()) return; setCreating(true); try { - await aethexCollabService.createTask(projectId, title.trim(), description.trim() || null, null, null); + await aethexCollabService.createTask( + projectId, + title.trim(), + description.trim() || null, + null, + null, + ); setTitle(""); setDescription(""); await load(); @@ -68,12 +89,18 @@ export default function ProjectBoard() { } }; - const move = async (taskId: string, status: "todo"|"doing"|"done"|"blocked") => { + const move = async ( + taskId: string, + status: "todo" | "doing" | "done" | "blocked", + ) => { await aethexCollabService.updateTaskStatus(taskId, status); await load(); }; - if (loading || isLoading) return ; + if (loading || isLoading) + return ( + + ); if (!user) return null; return ( @@ -81,17 +108,29 @@ export default function ProjectBoard() {
-

Project Board

-

Track tasks by status. Drag-and-drop coming next.

+

+ Project Board +

+

+ Track tasks by status. Drag-and-drop coming next. +

{columns.map((col) => ( - + {col.title} - {grouped[col.key].length} + + {grouped[col.key].length} + {col.hint} @@ -100,14 +139,26 @@ export default function ProjectBoard() {

No tasks.

) : ( grouped[col.key].map((t) => ( -
-
{t.title}
+
+
+ {t.title} +
{t.description ? ( -

{t.description}

+

+ {t.description} +

) : null}
{columns.map((k) => ( - ))} @@ -123,13 +174,27 @@ export default function ProjectBoard() { Add task - Keep titles concise; details optional. + + Keep titles concise; details optional. + - setTitle(e.target.value)} /> -