Prettier format pending files

This commit is contained in:
Builder.io 2025-09-27 20:58:59 +00:00
parent 191460bf71
commit 385536e3ad
4 changed files with 180 additions and 123 deletions

View file

@ -3,7 +3,10 @@ import { User, Session } from "@supabase/supabase-js";
import { supabase } from "@/lib/supabase";
import { UserProfile } from "@/lib/database.types";
import { aethexToast } from "@/lib/aethex-toast";
import { aethexUserService, type AethexUserProfile } from "@/lib/aethex-database-adapter";
import {
aethexUserService,
type AethexUserProfile,
} from "@/lib/aethex-database-adapter";
interface AuthContextType {
user: User | null;
@ -123,8 +126,12 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({
console.error("SignIn error details:", error);
let errorMessage = error.message;
if (error.message?.includes("Failed to fetch") || error.name === "AuthRetryableFetchError") {
errorMessage = "Unable to connect to authentication service. Please check your internet connection and try again.";
if (
error.message?.includes("Failed to fetch") ||
error.name === "AuthRetryableFetchError"
) {
errorMessage =
"Unable to connect to authentication service. Please check your internet connection and try again.";
}
aethexToast.error({
@ -151,7 +158,8 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({
if (data.user) {
aethexToast.success({
title: "Account created!",
description: "Please check your email to verify your account, then sign in.",
description:
"Please check your email to verify your account, then sign in.",
});
}
} catch (error: any) {

View file

@ -13,7 +13,7 @@ console.log("Supabase Config:", {
hasKey: !!supabaseAnonKey,
url: supabaseUrl,
keyPrefix: supabaseAnonKey?.substring(0, 20) + "...",
isSupabaseConfigured
isSupabaseConfigured,
});
let supabaseClient: any = null;
@ -31,12 +31,18 @@ if (isSupabaseConfigured) {
setTimeout(async () => {
try {
console.log("🔍 Testing Supabase connection to:", supabaseUrl);
const { data, error } = await supabaseClient.from('user_profiles').select('count', { count: 'exact', head: true });
const { data, error } = await supabaseClient
.from("user_profiles")
.select("count", { count: "exact", head: true });
if (error) {
console.warn("⚠️ Supabase connection test failed:", error.message);
console.log("🔄 Falling back to mock authentication for development");
} else {
console.log("✅ Supabase connection successful - found", data, "user profiles");
console.log(
"✅ Supabase connection successful - found",
data,
"user profiles",
);
}
} catch (err: any) {
console.warn("⚠️ Supabase connection error:", err.message);
@ -61,7 +67,7 @@ if (isSupabaseConfigured) {
// Create a proxy that falls back to mock when Supabase fails
export const supabase = new Proxy(supabaseClient || {}, {
get(target, prop) {
if (prop === 'auth') {
if (prop === "auth") {
return {
signInWithPassword: async (credentials: any) => {
if (isSupabaseConfigured && target && target.auth) {
@ -72,17 +78,27 @@ export const supabase = new Proxy(supabaseClient || {}, {
return result;
} catch (error: any) {
console.warn("⚠️ Supabase authentication failed:", error.message);
if (error.message?.includes('Failed to fetch') ||
error.name === 'AuthRetryableFetchError' ||
error.message?.includes('fetch')) {
if (
error.message?.includes("Failed to fetch") ||
error.name === "AuthRetryableFetchError" ||
error.message?.includes("fetch")
) {
console.log("🔄 Falling back to mock authentication");
return await mockAuth.signInWithPassword(credentials.email, credentials.password);
return await mockAuth.signInWithPassword(
credentials.email,
credentials.password,
);
}
throw error;
}
} else {
console.log("🔄 Using mock authentication (Supabase not configured)");
return await mockAuth.signInWithPassword(credentials.email, credentials.password);
console.log(
"🔄 Using mock authentication (Supabase not configured)",
);
return await mockAuth.signInWithPassword(
credentials.email,
credentials.password,
);
}
},
signOut: async () => {
@ -124,12 +140,12 @@ export const supabase = new Proxy(supabaseClient || {}, {
}
}
return mockAuth.onAuthStateChange(callback);
}
},
};
}
if (prop === 'from') {
if (isSupabaseConfigured && target && typeof target.from === 'function') {
if (prop === "from") {
if (isSupabaseConfigured && target && typeof target.from === "function") {
return target.from.bind(target);
}
@ -147,16 +163,20 @@ export const supabase = new Proxy(supabaseClient || {}, {
single: async () => ({ data: rows[0] ?? {}, error: null }),
then: (resolve: any) => resolve({ data: rows, error: null }),
catch: () => builder,
finally: (cb: any) => { cb?.(); return builder; },
finally: (cb: any) => {
cb?.();
return builder;
},
};
return builder;
};
const createMockTable = (table: string) => ({
select: (_cols?: any, _opts?: any) => createMockBuilder([]),
insert: (payload?: any) => createMockBuilder(
Array.isArray(payload) ? payload : payload ? [payload] : [],
),
insert: (payload?: any) =>
createMockBuilder(
Array.isArray(payload) ? payload : payload ? [payload] : [],
),
update: (payload?: any) => createMockBuilder(payload || {}),
delete: () => createMockBuilder([]),
});
@ -165,7 +185,7 @@ export const supabase = new Proxy(supabaseClient || {}, {
}
return target[prop];
}
},
});
// Auth helpers
@ -189,7 +209,7 @@ export const channel = supabase.channel;
try {
const testLogin = await supabase.auth.signInWithPassword({
email: "test@example.com",
password: "test123"
password: "test123",
});
console.log("Auth test result:", testLogin);
} catch (error) {
@ -197,7 +217,10 @@ export const channel = supabase.channel;
}
try {
const { data, error } = await supabase.from('user_profiles').select('*').limit(1);
const { data, error } = await supabase
.from("user_profiles")
.select("*")
.limit(1);
console.log("Database test - data:", data, "error:", error);
} catch (dbError) {
console.error("Database test error:", dbError);

View file

@ -55,7 +55,11 @@ export default function Dashboard() {
});
useEffect(() => {
console.log("Dashboard useEffect:", { user: !!user, profile: !!profile, authLoading });
console.log("Dashboard useEffect:", {
user: !!user,
profile: !!profile,
authLoading,
});
// Only redirect to login when auth is resolved and there's no user
if (!user && !authLoading) {
@ -97,7 +101,9 @@ export default function Dashboard() {
// Load user's achievements with error handling
let userAchievements = [];
try {
userAchievements = await aethexAchievementService.getUserAchievements(user!.id);
userAchievements = await aethexAchievementService.getUserAchievements(
user!.id,
);
setAchievements(userAchievements);
} catch (achievementError) {
console.warn("Could not load achievements:", achievementError);
@ -283,8 +289,12 @@ export default function Dashboard() {
<div className="flex items-center space-x-3">
<User className="h-5 w-5 text-orange-400" />
<div>
<h3 className="text-white font-semibold">Complete Your Profile</h3>
<p className="text-orange-200 text-sm">Set up your profile to unlock all features</p>
<h3 className="text-white font-semibold">
Complete Your Profile
</h3>
<p className="text-orange-200 text-sm">
Set up your profile to unlock all features
</p>
</div>
</div>
<div className="flex space-x-2">
@ -315,10 +325,12 @@ export default function Dashboard() {
<div className="flex flex-col lg:flex-row justify-between items-start lg:items-center gap-4">
<div>
<h1 className="text-3xl font-bold text-gradient-purple">
Welcome back, {profile?.full_name || user.email?.split('@')[0]}
Welcome back,{" "}
{profile?.full_name || user.email?.split("@")[0]}
</h1>
<p className="text-muted-foreground">
{profile?.role || 'Member'} Level {profile?.level || 1} 7 day streak 🔥
{profile?.role || "Member"} Level {profile?.level || 1} 7
day streak 🔥
</p>
</div>
<div className="flex items-center space-x-4">
@ -343,7 +355,10 @@ export default function Dashboard() {
<div className="text-center space-y-4">
<div className="relative">
<img
src={profile?.avatar_url || 'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=400&h=400&fit=crop&crop=face'}
src={
profile?.avatar_url ||
"https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=400&h=400&fit=crop&crop=face"
}
alt="User Avatar"
className="w-20 h-20 rounded-full mx-auto ring-4 ring-aethex-400/20 hover:ring-aethex-400/50 transition-all duration-300"
/>
@ -351,10 +366,10 @@ export default function Dashboard() {
</div>
<div>
<h3 className="font-semibold text-gradient">
{profile?.full_name || user.email?.split('@')[0]}
{profile?.full_name || user.email?.split("@")[0]}
</h3>
<p className="text-sm text-muted-foreground">
{profile?.role || 'Member'}
{profile?.role || "Member"}
</p>
<Badge
variant="outline"
@ -369,7 +384,8 @@ export default function Dashboard() {
<div className="flex justify-between text-sm">
<span>XP Progress</span>
<span>
{profile?.total_xp || 0} / {((profile?.level || 1) * 1000)}
{profile?.total_xp || 0} /{" "}
{(profile?.level || 1) * 1000}
</span>
</div>
<div className="w-full bg-muted rounded-full h-2">
@ -481,58 +497,60 @@ export default function Dashboard() {
</div>
) : (
projects.slice(0, 3).map((project: any, index) => (
<div
key={index}
className="flex items-center justify-between p-4 rounded-lg border border-border/30 hover:border-aethex-400/50 transition-all duration-300 hover-lift animate-slide-right"
style={{ animationDelay: `${index * 0.1}s` }}
>
<div className="flex items-center space-x-4">
<div className="w-12 h-12 rounded-lg bg-gradient-to-r from-aethex-500/20 to-neon-blue/20 flex items-center justify-center">
<Rocket className="h-6 w-6 text-aethex-400" />
</div>
<div>
<h4 className="font-semibold">{project.title}</h4>
<p className="text-sm text-muted-foreground">
{project.status?.replace("_", " ").toUpperCase()} {" "}
{project.technologies?.slice(0, 2).join(", ") ||
"No tech specified"}
</p>
</div>
</div>
<div className="flex items-center space-x-4">
<div className="text-right">
<p className="text-sm font-medium">
{getProgressPercentage(project)}%
</p>
<div className="w-20 bg-muted rounded-full h-2 mt-1">
<div
className="bg-gradient-to-r from-aethex-500 to-neon-blue h-2 rounded-full"
style={{
width: `${getProgressPercentage(project)}%`,
}}
/>
<div
key={index}
className="flex items-center justify-between p-4 rounded-lg border border-border/30 hover:border-aethex-400/50 transition-all duration-300 hover-lift animate-slide-right"
style={{ animationDelay: `${index * 0.1}s` }}
>
<div className="flex items-center space-x-4">
<div className="w-12 h-12 rounded-lg bg-gradient-to-r from-aethex-500/20 to-neon-blue/20 flex items-center justify-center">
<Rocket className="h-6 w-6 text-aethex-400" />
</div>
<div>
<h4 className="font-semibold">{project.title}</h4>
<p className="text-sm text-muted-foreground">
{project.status?.replace("_", " ").toUpperCase()}{" "}
{" "}
{project.technologies?.slice(0, 2).join(", ") ||
"No tech specified"}
</p>
</div>
</div>
<Badge
variant={
getPriorityFromTech(project.technologies || []) ===
"High"
? "destructive"
: "secondary"
}
className="animate-pulse"
>
{getPriorityFromTech(project.technologies || [])}
</Badge>
<Button
variant="ghost"
size="sm"
className="hover-lift"
>
<MoreHorizontal className="h-4 w-4" />
</Button>
<div className="flex items-center space-x-4">
<div className="text-right">
<p className="text-sm font-medium">
{getProgressPercentage(project)}%
</p>
<div className="w-20 bg-muted rounded-full h-2 mt-1">
<div
className="bg-gradient-to-r from-aethex-500 to-neon-blue h-2 rounded-full"
style={{
width: `${getProgressPercentage(project)}%`,
}}
/>
</div>
</div>
<Badge
variant={
getPriorityFromTech(
project.technologies || [],
) === "High"
? "destructive"
: "secondary"
}
className="animate-pulse"
>
{getPriorityFromTech(project.technologies || [])}
</Badge>
<Button
variant="ghost"
size="sm"
className="hover-lift"
>
<MoreHorizontal className="h-4 w-4" />
</Button>
</div>
</div>
</div>
))
)}
</CardContent>
@ -551,49 +569,54 @@ export default function Dashboard() {
{achievements.length === 0 ? (
<div className="col-span-full text-center py-8 text-muted-foreground">
<Trophy className="h-12 w-12 mx-auto mb-4 opacity-50" />
<p>No achievements unlocked yet. Complete projects to earn achievements!</p>
<p>
No achievements unlocked yet. Complete projects to
earn achievements!
</p>
</div>
) : (
achievements.map((achievement: any, index) => {
const Icon = getAchievementIcon(achievement.icon || 'star');
return (
<div
key={index}
className={`p-4 rounded-lg border transition-all duration-300 hover-lift animate-scale-in ${
achievement.earned
? "border-aethex-400/50 bg-aethex-500/10"
: "border-border/30 opacity-60"
}`}
style={{ animationDelay: `${index * 0.1}s` }}
>
<div className="flex items-center space-x-3">
<div
className={`p-2 rounded-lg ${
achievement.earned
? "bg-gradient-to-r from-aethex-500 to-neon-blue"
: "bg-muted"
}`}
>
<Icon
className={`h-5 w-5 ${achievement.earned ? "text-white" : "text-muted-foreground"}`}
/>
</div>
<div>
<h4
className={`font-semibold ${achievement.earned ? "text-gradient" : ""}`}
const Icon = getAchievementIcon(
achievement.icon || "star",
);
return (
<div
key={index}
className={`p-4 rounded-lg border transition-all duration-300 hover-lift animate-scale-in ${
achievement.earned
? "border-aethex-400/50 bg-aethex-500/10"
: "border-border/30 opacity-60"
}`}
style={{ animationDelay: `${index * 0.1}s` }}
>
<div className="flex items-center space-x-3">
<div
className={`p-2 rounded-lg ${
achievement.earned
? "bg-gradient-to-r from-aethex-500 to-neon-blue"
: "bg-muted"
}`}
>
{achievement.title}
</h4>
<p className="text-sm text-muted-foreground">
{achievement.description}
</p>
<Icon
className={`h-5 w-5 ${achievement.earned ? "text-white" : "text-muted-foreground"}`}
/>
</div>
<div>
<h4
className={`font-semibold ${achievement.earned ? "text-gradient" : ""}`}
>
{achievement.title}
</h4>
<p className="text-sm text-muted-foreground">
{achievement.description}
</p>
</div>
{achievement.earned && (
<Star className="h-5 w-5 text-yellow-500 animate-pulse" />
)}
</div>
{achievement.earned && (
<Star className="h-5 w-5 text-yellow-500 animate-pulse" />
)}
</div>
</div>
);
);
})
)}
</div>

View file

@ -123,8 +123,10 @@ export default function Onboarding() {
const existing = await aethexUserService.getCurrentUser();
const payload = {
username: `${data.personalInfo.firstName || user.email?.split("@")[0] || "user"}`,
full_name: `${data.personalInfo.firstName} ${data.personalInfo.lastName}`.trim(),
user_type: (userTypeMap[data.userType || "member"] as any) || "community_member",
full_name:
`${data.personalInfo.firstName} ${data.personalInfo.lastName}`.trim(),
user_type:
(userTypeMap[data.userType || "member"] as any) || "community_member",
experience_level: (data.experience.level as any) || "beginner",
bio: data.experience.previousProjects || undefined,
} as any;
@ -157,7 +159,8 @@ export default function Onboarding() {
function formatError(err: any) {
if (!err) return "Unknown error";
if (typeof err === "string") return err;
if (err instanceof Error) return err.message + (err.stack ? `\n${err.stack}` : "");
if (err instanceof Error)
return err.message + (err.stack ? `\n${err.stack}` : "");
if ((err as any).message) return (err as any).message;
try {
return JSON.stringify(err);