@braintwopoint0/playback-commons 0.1.13 → 0.1.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -93,9 +93,15 @@ import { useRouter } from "next/navigation";
93
93
  // src/supabase/client.ts
94
94
  import { createBrowserClient } from "@supabase/ssr";
95
95
  function createClient() {
96
+ const cookieDomain = process.env.NEXT_PUBLIC_COOKIE_DOMAIN;
96
97
  return createBrowserClient(
97
98
  process.env.NEXT_PUBLIC_SUPABASE_URL,
98
- process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
99
+ process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY,
100
+ {
101
+ ...cookieDomain && {
102
+ cookieOptions: { domain: cookieDomain }
103
+ }
104
+ }
99
105
  );
100
106
  }
101
107
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/auth/shared.ts","../../src/auth/context.tsx","../../src/supabase/client.ts"],"sourcesContent":["import { User } from '@supabase/supabase-js'\n\nexport function validateEmail(email: string): boolean {\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/\n return emailRegex.test(email)\n}\n\nexport function validatePassword(password: string): {\n isValid: boolean\n errors: string[]\n} {\n const errors: string[] = []\n\n if (password.length < 8) {\n errors.push('Password must be at least 8 characters long')\n }\n\n if (!/(?=.*[a-z])/.test(password)) {\n errors.push('Password must contain at least one lowercase letter')\n }\n\n if (!/(?=.*[A-Z])/.test(password)) {\n errors.push('Password must contain at least one uppercase letter')\n }\n\n if (!/(?=.*\\d)/.test(password)) {\n errors.push('Password must contain at least one number')\n }\n\n return {\n isValid: errors.length === 0,\n errors,\n }\n}\n\nexport function validateUsername(username: string): {\n isValid: boolean\n errors: string[]\n} {\n const errors: string[] = []\n\n if (username.length < 3) {\n errors.push('Username must be at least 3 characters long')\n }\n\n if (username.length > 30) {\n errors.push('Username cannot be longer than 30 characters')\n }\n\n if (!/^[a-zA-Z0-9_-]+$/.test(username)) {\n errors.push(\n 'Username can only contain letters, numbers, underscores, and hyphens'\n )\n }\n\n return {\n isValid: errors.length === 0,\n errors,\n }\n}\n\nexport function hasRole(user: User | null, role: string): boolean {\n if (!user) return false\n return user.user_metadata?.role === role\n}\n\nexport function hasAnyRole(user: User | null, roles: string[]): boolean {\n if (!user) return false\n return roles.includes(user.user_metadata?.role)\n}\n\nexport function isPlayer(user: User | null): boolean {\n return hasRole(user, 'player')\n}\n\nexport function isCoach(user: User | null): boolean {\n return hasRole(user, 'coach')\n}\n\nexport function isScout(user: User | null): boolean {\n return hasRole(user, 'scout')\n}\n\nexport function isFan(user: User | null): boolean {\n return hasRole(user, 'fan')\n}\n\nexport function getAuthErrorMessage(error: any): string {\n if (!error) return 'An unknown error occurred'\n\n const message = error.message || error.error_description || error.toString()\n\n const errorMappings: Record<string, string> = {\n 'Invalid login credentials':\n 'Invalid email or password. Please check your credentials and try again.',\n 'Email not confirmed':\n 'Please check your email and click the confirmation link before signing in.',\n 'User already registered':\n 'An account with this email address already exists. Please sign in instead.',\n 'Password should be at least 6 characters':\n 'Password must be at least 6 characters long.',\n 'Signup requires a valid password': 'Please provide a valid password.',\n 'Invalid email': 'Please provide a valid email address.',\n 'Email rate limit exceeded':\n 'Too many emails sent. Please wait before requesting another.',\n 'duplicate key value violates unique constraint \"profiles_username_key\"':\n 'This username is already taken. Please choose a different username.',\n }\n\n return errorMappings[message] || message\n}\n","'use client'\n\nimport {\n createContext,\n useContext,\n useEffect,\n useState,\n useMemo,\n useCallback,\n useRef,\n} from 'react'\nimport { User, Session, AuthError } from '@supabase/supabase-js'\nimport { useRouter } from 'next/navigation'\nimport { createClient } from '../supabase/client'\n\ninterface UserProfile {\n id: string\n user_id: string\n username: string\n email: string | null\n full_name: string | null\n bio: string | null\n avatar_url: string | null\n cover_image_url: string | null\n date_of_birth: string | null\n height_cm: number | null\n weight_kg: number | null\n nationality: string | null\n location: string | null\n phone: string | null\n website: string | null\n social_links: any\n is_public: boolean | null\n created_at: string | null\n updated_at: string | null\n}\n\ninterface ProfileState {\n data: UserProfile | null\n loading: boolean\n error: string | null\n lastFetched: number | null\n}\n\ninterface AuthContextType {\n user: User | null\n session: Session | null\n loading: boolean\n profile: ProfileState\n isOnboardingComplete: boolean\n signUp: (\n email: string,\n password: string,\n metadata?: Record<string, any>\n ) => Promise<{ data: any; error: AuthError | null }>\n signIn: (\n email: string,\n password: string\n ) => Promise<{ error: AuthError | null }>\n signOut: () => Promise<{ error: AuthError | null }>\n resetPassword: (email: string) => Promise<{ error: AuthError | null }>\n refreshProfile: (force?: boolean) => Promise<void>\n updateProfile: (updates: Partial<UserProfile>) => void\n}\n\nconst AuthContext = createContext<AuthContextType | undefined>(undefined)\n\nconst CACHE_TIMEOUT = 5 * 60 * 1000\n\nexport function AuthProvider({\n children,\n}: {\n children: React.ReactNode\n}) {\n const [user, setUser] = useState<User | null>(null)\n const [session, setSession] = useState<Session | null>(null)\n const [loading, setLoading] = useState(true)\n const [profile, setProfile] = useState<ProfileState>({\n data: null,\n loading: false,\n error: null,\n lastFetched: null,\n })\n\n const router = useRouter()\n const routerRef = useRef(router)\n routerRef.current = router\n const supabase = useMemo(() => createClient(), [])\n const profileRef = useRef(profile)\n profileRef.current = profile\n\n const isOnboardingComplete = useMemo(() => {\n return !!profile.data\n }, [profile.data])\n\n const fetchProfile = useCallback(\n async (userId: string) => {\n try {\n const { data: profileData, error: profileError } = await supabase\n .from('profiles')\n .select('*')\n .eq('user_id', userId)\n .single()\n\n if (profileError) throw profileError\n\n return { data: profileData, error: null }\n } catch (error) {\n return {\n data: null,\n error:\n error instanceof Error ? error.message : 'Failed to fetch profile',\n }\n }\n },\n [supabase]\n )\n\n const refreshProfile = useCallback(\n async (force = false) => {\n if (!user) {\n setProfile({\n data: null,\n loading: false,\n error: null,\n lastFetched: null,\n })\n return\n }\n\n const now = Date.now()\n const current = profileRef.current\n const isCacheValid =\n current.lastFetched && now - current.lastFetched < CACHE_TIMEOUT\n\n if (!force && isCacheValid && current.data) {\n return\n }\n\n setProfile((prev) => ({ ...prev, loading: true, error: null }))\n\n try {\n const result = await fetchProfile(user.id)\n setProfile({\n data: result.data,\n loading: false,\n error: result.error,\n lastFetched: now,\n })\n } catch (error) {\n setProfile((prev) => ({\n ...prev,\n loading: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n }))\n }\n },\n [user, fetchProfile]\n )\n\n const updateProfile = useCallback((updates: Partial<UserProfile>) => {\n setProfile((prev) => ({\n ...prev,\n data: prev.data ? { ...prev.data, ...updates } : null,\n }))\n }, [])\n\n useEffect(() => {\n const initializeAuth = async () => {\n try {\n const {\n data: { session },\n error,\n } = await supabase.auth.getSession()\n\n if (error) {\n console.error('Error getting session:', error)\n } else {\n setSession(session)\n setUser(session?.user ?? null)\n\n if (session?.user) {\n setProfile({\n data: null,\n loading: false,\n error: null,\n lastFetched: null,\n })\n }\n }\n } catch (error) {\n console.error('Session initialization error:', error)\n } finally {\n setLoading(false)\n }\n }\n\n initializeAuth()\n }, [supabase.auth])\n\n useEffect(() => {\n if (!loading && user && !profile.data && !profile.loading) {\n const loadProfile = async () => {\n setProfile((prev) => ({ ...prev, loading: true, error: null }))\n try {\n const result = await fetchProfile(user.id)\n setProfile({\n data: result.data,\n loading: false,\n error: result.error,\n lastFetched: Date.now(),\n })\n } catch (error) {\n setProfile((prev) => ({\n ...prev,\n loading: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n }))\n }\n }\n loadProfile()\n }\n }, [loading, user, profile.data, profile.loading, fetchProfile])\n\n useEffect(() => {\n let isInitialEvent = true\n let currentUserId: string | null = null\n\n const {\n data: { subscription },\n } = supabase.auth.onAuthStateChange(async (event, session) => {\n const newUserId = session?.user?.id ?? null\n\n // Only update user/session state if the user actually changed\n // This prevents new object references from causing cascading re-renders\n // on TOKEN_REFRESHED and INITIAL_SESSION events\n if (newUserId !== currentUserId) {\n currentUserId = newUserId\n setSession(session)\n setUser(session?.user ?? null)\n }\n setLoading(false)\n\n // Only reset profile on sign out — signing in triggers the profile\n // fetch useEffect naturally via the user state change\n if (event === 'SIGNED_OUT') {\n setProfile({\n data: null,\n loading: false,\n error: null,\n lastFetched: null,\n })\n }\n\n // Skip router actions on initial mount to avoid refresh loops\n if (isInitialEvent) {\n isInitialEvent = false\n return\n }\n\n if (event === 'SIGNED_OUT') {\n routerRef.current.push('/')\n routerRef.current.refresh()\n }\n })\n\n return () => subscription.unsubscribe()\n }, [supabase.auth])\n\n const signUp = useCallback(\n async (email: string, password: string, metadata?: Record<string, any>) => {\n setLoading(true)\n try {\n const { data, error } = await supabase.auth.signUp({\n email,\n password,\n options: {\n data: metadata,\n emailRedirectTo: `${window.location.origin}/auth/callback`,\n },\n })\n return { data, error }\n } finally {\n setLoading(false)\n }\n },\n [supabase.auth]\n )\n\n const signIn = useCallback(\n async (email: string, password: string) => {\n setLoading(true)\n try {\n const { error } = await supabase.auth.signInWithPassword({\n email,\n password,\n })\n return { error }\n } finally {\n setLoading(false)\n }\n },\n [supabase.auth]\n )\n\n const signOut = useCallback(async () => {\n setLoading(true)\n try {\n const { error } = await supabase.auth.signOut()\n return { error }\n } finally {\n setLoading(false)\n }\n }, [supabase.auth])\n\n const resetPassword = useCallback(\n async (email: string) => {\n const { error } = await supabase.auth.resetPasswordForEmail(email, {\n redirectTo: `${window.location.origin}/auth/reset-password`,\n })\n return { error }\n },\n [supabase.auth]\n )\n\n const value = useMemo(\n () => ({\n user,\n session,\n loading,\n profile,\n isOnboardingComplete,\n signUp,\n signIn,\n signOut,\n resetPassword,\n refreshProfile,\n updateProfile,\n }),\n [\n user,\n session,\n loading,\n profile,\n isOnboardingComplete,\n refreshProfile,\n updateProfile,\n signIn,\n signOut,\n resetPassword,\n signUp,\n ]\n )\n\n return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>\n}\n\nexport function useAuth() {\n const context = useContext(AuthContext)\n if (context === undefined) {\n throw new Error('useAuth must be used within an AuthProvider')\n }\n return context\n}\n\nexport function useProfile() {\n const { profile, refreshProfile, updateProfile } = useAuth()\n return { profile, refreshProfile, updateProfile }\n}\n\nexport function useOnboardingStatus() {\n const { isOnboardingComplete, profile } = useAuth()\n return {\n isComplete: isOnboardingComplete,\n loading: profile.loading,\n error: profile.error,\n }\n}\n","import { createBrowserClient } from '@supabase/ssr'\n\nexport function createClient() {\n return createBrowserClient(\n process.env.NEXT_PUBLIC_SUPABASE_URL!,\n process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!\n )\n}\n"],"mappings":"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","names":["session"]}
1
+ {"version":3,"sources":["../../src/auth/shared.ts","../../src/auth/context.tsx","../../src/supabase/client.ts"],"sourcesContent":["import { User } from '@supabase/supabase-js'\n\nexport function validateEmail(email: string): boolean {\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/\n return emailRegex.test(email)\n}\n\nexport function validatePassword(password: string): {\n isValid: boolean\n errors: string[]\n} {\n const errors: string[] = []\n\n if (password.length < 8) {\n errors.push('Password must be at least 8 characters long')\n }\n\n if (!/(?=.*[a-z])/.test(password)) {\n errors.push('Password must contain at least one lowercase letter')\n }\n\n if (!/(?=.*[A-Z])/.test(password)) {\n errors.push('Password must contain at least one uppercase letter')\n }\n\n if (!/(?=.*\\d)/.test(password)) {\n errors.push('Password must contain at least one number')\n }\n\n return {\n isValid: errors.length === 0,\n errors,\n }\n}\n\nexport function validateUsername(username: string): {\n isValid: boolean\n errors: string[]\n} {\n const errors: string[] = []\n\n if (username.length < 3) {\n errors.push('Username must be at least 3 characters long')\n }\n\n if (username.length > 30) {\n errors.push('Username cannot be longer than 30 characters')\n }\n\n if (!/^[a-zA-Z0-9_-]+$/.test(username)) {\n errors.push(\n 'Username can only contain letters, numbers, underscores, and hyphens'\n )\n }\n\n return {\n isValid: errors.length === 0,\n errors,\n }\n}\n\nexport function hasRole(user: User | null, role: string): boolean {\n if (!user) return false\n return user.user_metadata?.role === role\n}\n\nexport function hasAnyRole(user: User | null, roles: string[]): boolean {\n if (!user) return false\n return roles.includes(user.user_metadata?.role)\n}\n\nexport function isPlayer(user: User | null): boolean {\n return hasRole(user, 'player')\n}\n\nexport function isCoach(user: User | null): boolean {\n return hasRole(user, 'coach')\n}\n\nexport function isScout(user: User | null): boolean {\n return hasRole(user, 'scout')\n}\n\nexport function isFan(user: User | null): boolean {\n return hasRole(user, 'fan')\n}\n\nexport function getAuthErrorMessage(error: any): string {\n if (!error) return 'An unknown error occurred'\n\n const message = error.message || error.error_description || error.toString()\n\n const errorMappings: Record<string, string> = {\n 'Invalid login credentials':\n 'Invalid email or password. Please check your credentials and try again.',\n 'Email not confirmed':\n 'Please check your email and click the confirmation link before signing in.',\n 'User already registered':\n 'An account with this email address already exists. Please sign in instead.',\n 'Password should be at least 6 characters':\n 'Password must be at least 6 characters long.',\n 'Signup requires a valid password': 'Please provide a valid password.',\n 'Invalid email': 'Please provide a valid email address.',\n 'Email rate limit exceeded':\n 'Too many emails sent. Please wait before requesting another.',\n 'duplicate key value violates unique constraint \"profiles_username_key\"':\n 'This username is already taken. Please choose a different username.',\n }\n\n return errorMappings[message] || message\n}\n","'use client'\n\nimport {\n createContext,\n useContext,\n useEffect,\n useState,\n useMemo,\n useCallback,\n useRef,\n} from 'react'\nimport { User, Session, AuthError } from '@supabase/supabase-js'\nimport { useRouter } from 'next/navigation'\nimport { createClient } from '../supabase/client'\n\ninterface UserProfile {\n id: string\n user_id: string\n username: string\n email: string | null\n full_name: string | null\n bio: string | null\n avatar_url: string | null\n cover_image_url: string | null\n date_of_birth: string | null\n height_cm: number | null\n weight_kg: number | null\n nationality: string | null\n location: string | null\n phone: string | null\n website: string | null\n social_links: any\n is_public: boolean | null\n created_at: string | null\n updated_at: string | null\n}\n\ninterface ProfileState {\n data: UserProfile | null\n loading: boolean\n error: string | null\n lastFetched: number | null\n}\n\ninterface AuthContextType {\n user: User | null\n session: Session | null\n loading: boolean\n profile: ProfileState\n isOnboardingComplete: boolean\n signUp: (\n email: string,\n password: string,\n metadata?: Record<string, any>\n ) => Promise<{ data: any; error: AuthError | null }>\n signIn: (\n email: string,\n password: string\n ) => Promise<{ error: AuthError | null }>\n signOut: () => Promise<{ error: AuthError | null }>\n resetPassword: (email: string) => Promise<{ error: AuthError | null }>\n refreshProfile: (force?: boolean) => Promise<void>\n updateProfile: (updates: Partial<UserProfile>) => void\n}\n\nconst AuthContext = createContext<AuthContextType | undefined>(undefined)\n\nconst CACHE_TIMEOUT = 5 * 60 * 1000\n\nexport function AuthProvider({\n children,\n}: {\n children: React.ReactNode\n}) {\n const [user, setUser] = useState<User | null>(null)\n const [session, setSession] = useState<Session | null>(null)\n const [loading, setLoading] = useState(true)\n const [profile, setProfile] = useState<ProfileState>({\n data: null,\n loading: false,\n error: null,\n lastFetched: null,\n })\n\n const router = useRouter()\n const routerRef = useRef(router)\n routerRef.current = router\n const supabase = useMemo(() => createClient(), [])\n const profileRef = useRef(profile)\n profileRef.current = profile\n\n const isOnboardingComplete = useMemo(() => {\n return !!profile.data\n }, [profile.data])\n\n const fetchProfile = useCallback(\n async (userId: string) => {\n try {\n const { data: profileData, error: profileError } = await supabase\n .from('profiles')\n .select('*')\n .eq('user_id', userId)\n .single()\n\n if (profileError) throw profileError\n\n return { data: profileData, error: null }\n } catch (error) {\n return {\n data: null,\n error:\n error instanceof Error ? error.message : 'Failed to fetch profile',\n }\n }\n },\n [supabase]\n )\n\n const refreshProfile = useCallback(\n async (force = false) => {\n if (!user) {\n setProfile({\n data: null,\n loading: false,\n error: null,\n lastFetched: null,\n })\n return\n }\n\n const now = Date.now()\n const current = profileRef.current\n const isCacheValid =\n current.lastFetched && now - current.lastFetched < CACHE_TIMEOUT\n\n if (!force && isCacheValid && current.data) {\n return\n }\n\n setProfile((prev) => ({ ...prev, loading: true, error: null }))\n\n try {\n const result = await fetchProfile(user.id)\n setProfile({\n data: result.data,\n loading: false,\n error: result.error,\n lastFetched: now,\n })\n } catch (error) {\n setProfile((prev) => ({\n ...prev,\n loading: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n }))\n }\n },\n [user, fetchProfile]\n )\n\n const updateProfile = useCallback((updates: Partial<UserProfile>) => {\n setProfile((prev) => ({\n ...prev,\n data: prev.data ? { ...prev.data, ...updates } : null,\n }))\n }, [])\n\n useEffect(() => {\n const initializeAuth = async () => {\n try {\n const {\n data: { session },\n error,\n } = await supabase.auth.getSession()\n\n if (error) {\n console.error('Error getting session:', error)\n } else {\n setSession(session)\n setUser(session?.user ?? null)\n\n if (session?.user) {\n setProfile({\n data: null,\n loading: false,\n error: null,\n lastFetched: null,\n })\n }\n }\n } catch (error) {\n console.error('Session initialization error:', error)\n } finally {\n setLoading(false)\n }\n }\n\n initializeAuth()\n }, [supabase.auth])\n\n useEffect(() => {\n if (!loading && user && !profile.data && !profile.loading) {\n const loadProfile = async () => {\n setProfile((prev) => ({ ...prev, loading: true, error: null }))\n try {\n const result = await fetchProfile(user.id)\n setProfile({\n data: result.data,\n loading: false,\n error: result.error,\n lastFetched: Date.now(),\n })\n } catch (error) {\n setProfile((prev) => ({\n ...prev,\n loading: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n }))\n }\n }\n loadProfile()\n }\n }, [loading, user, profile.data, profile.loading, fetchProfile])\n\n useEffect(() => {\n let isInitialEvent = true\n let currentUserId: string | null = null\n\n const {\n data: { subscription },\n } = supabase.auth.onAuthStateChange(async (event, session) => {\n const newUserId = session?.user?.id ?? null\n\n // Only update user/session state if the user actually changed\n // This prevents new object references from causing cascading re-renders\n // on TOKEN_REFRESHED and INITIAL_SESSION events\n if (newUserId !== currentUserId) {\n currentUserId = newUserId\n setSession(session)\n setUser(session?.user ?? null)\n }\n setLoading(false)\n\n // Only reset profile on sign out — signing in triggers the profile\n // fetch useEffect naturally via the user state change\n if (event === 'SIGNED_OUT') {\n setProfile({\n data: null,\n loading: false,\n error: null,\n lastFetched: null,\n })\n }\n\n // Skip router actions on initial mount to avoid refresh loops\n if (isInitialEvent) {\n isInitialEvent = false\n return\n }\n\n if (event === 'SIGNED_OUT') {\n routerRef.current.push('/')\n routerRef.current.refresh()\n }\n })\n\n return () => subscription.unsubscribe()\n }, [supabase.auth])\n\n const signUp = useCallback(\n async (email: string, password: string, metadata?: Record<string, any>) => {\n setLoading(true)\n try {\n const { data, error } = await supabase.auth.signUp({\n email,\n password,\n options: {\n data: metadata,\n emailRedirectTo: `${window.location.origin}/auth/callback`,\n },\n })\n return { data, error }\n } finally {\n setLoading(false)\n }\n },\n [supabase.auth]\n )\n\n const signIn = useCallback(\n async (email: string, password: string) => {\n setLoading(true)\n try {\n const { error } = await supabase.auth.signInWithPassword({\n email,\n password,\n })\n return { error }\n } finally {\n setLoading(false)\n }\n },\n [supabase.auth]\n )\n\n const signOut = useCallback(async () => {\n setLoading(true)\n try {\n const { error } = await supabase.auth.signOut()\n return { error }\n } finally {\n setLoading(false)\n }\n }, [supabase.auth])\n\n const resetPassword = useCallback(\n async (email: string) => {\n const { error } = await supabase.auth.resetPasswordForEmail(email, {\n redirectTo: `${window.location.origin}/auth/reset-password`,\n })\n return { error }\n },\n [supabase.auth]\n )\n\n const value = useMemo(\n () => ({\n user,\n session,\n loading,\n profile,\n isOnboardingComplete,\n signUp,\n signIn,\n signOut,\n resetPassword,\n refreshProfile,\n updateProfile,\n }),\n [\n user,\n session,\n loading,\n profile,\n isOnboardingComplete,\n refreshProfile,\n updateProfile,\n signIn,\n signOut,\n resetPassword,\n signUp,\n ]\n )\n\n return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>\n}\n\nexport function useAuth() {\n const context = useContext(AuthContext)\n if (context === undefined) {\n throw new Error('useAuth must be used within an AuthProvider')\n }\n return context\n}\n\nexport function useProfile() {\n const { profile, refreshProfile, updateProfile } = useAuth()\n return { profile, refreshProfile, updateProfile }\n}\n\nexport function useOnboardingStatus() {\n const { isOnboardingComplete, profile } = useAuth()\n return {\n isComplete: isOnboardingComplete,\n loading: profile.loading,\n error: profile.error,\n }\n}\n","import { createBrowserClient } from '@supabase/ssr'\n\nexport function createClient() {\n const cookieDomain = process.env.NEXT_PUBLIC_COOKIE_DOMAIN\n\n return createBrowserClient(\n process.env.NEXT_PUBLIC_SUPABASE_URL!,\n process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,\n {\n ...(cookieDomain && {\n cookieOptions: { domain: cookieDomain },\n }),\n }\n )\n}\n"],"mappings":"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","names":["session"]}
@@ -3,9 +3,15 @@
3
3
  // src/supabase/client.ts
4
4
  import { createBrowserClient } from "@supabase/ssr";
5
5
  function createClient() {
6
+ const cookieDomain = process.env.NEXT_PUBLIC_COOKIE_DOMAIN;
6
7
  return createBrowserClient(
7
8
  process.env.NEXT_PUBLIC_SUPABASE_URL,
8
- process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
9
+ process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY,
10
+ {
11
+ ...cookieDomain && {
12
+ cookieOptions: { domain: cookieDomain }
13
+ }
14
+ }
9
15
  );
10
16
  }
11
17
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/supabase/client.ts"],"sourcesContent":["import { createBrowserClient } from '@supabase/ssr'\n\nexport function createClient() {\n return createBrowserClient(\n process.env.NEXT_PUBLIC_SUPABASE_URL!,\n process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!\n )\n}\n"],"mappings":";;;AAAA,SAAS,2BAA2B;AAE7B,SAAS,eAAe;AAC7B,SAAO;AAAA,IACL,QAAQ,IAAI;AAAA,IACZ,QAAQ,IAAI;AAAA,EACd;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/supabase/client.ts"],"sourcesContent":["import { createBrowserClient } from '@supabase/ssr'\n\nexport function createClient() {\n const cookieDomain = process.env.NEXT_PUBLIC_COOKIE_DOMAIN\n\n return createBrowserClient(\n process.env.NEXT_PUBLIC_SUPABASE_URL!,\n process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,\n {\n ...(cookieDomain && {\n cookieOptions: { domain: cookieDomain },\n }),\n }\n )\n}\n"],"mappings":";;;AAAA,SAAS,2BAA2B;AAE7B,SAAS,eAAe;AAC7B,QAAM,eAAe,QAAQ,IAAI;AAEjC,SAAO;AAAA,IACL,QAAQ,IAAI;AAAA,IACZ,QAAQ,IAAI;AAAA,IACZ;AAAA,MACE,GAAI,gBAAgB;AAAA,QAClB,eAAe,EAAE,QAAQ,aAAa;AAAA,MACxC;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
@@ -9,6 +9,13 @@ import * as SelectPrimitive from '@radix-ui/react-select';
9
9
  import * as PopoverPrimitive from '@radix-ui/react-popover';
10
10
  import { DayPicker, DayButton } from 'react-day-picker';
11
11
  import * as RechartsPrimitive from 'recharts';
12
+ import * as SeparatorPrimitive from '@radix-ui/react-separator';
13
+ import * as TabsPrimitive from '@radix-ui/react-tabs';
14
+ import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
15
+ import * as SwitchPrimitives from '@radix-ui/react-switch';
16
+ import * as CollapsiblePrimitive from '@radix-ui/react-collapsible';
17
+ import * as TooltipPrimitive from '@radix-ui/react-tooltip';
18
+ import * as AvatarPrimitive from '@radix-ui/react-avatar';
12
19
 
13
20
  declare const buttonVariants: (props?: ({
14
21
  variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" | "playback" | null | undefined;
@@ -195,6 +202,206 @@ declare function ChartLegendContent({ className, hideIcon, payload, verticalAlig
195
202
  nameKey?: string;
196
203
  }): react_jsx_runtime.JSX.Element | null;
197
204
 
205
+ declare function Skeleton({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
206
+
207
+ declare const Separator: React$1.ForwardRefExoticComponent<Omit<SeparatorPrimitive.SeparatorProps & React$1.RefAttributes<HTMLDivElement>, "ref"> & React$1.RefAttributes<HTMLDivElement>>;
208
+
209
+ declare const Tabs: React$1.ForwardRefExoticComponent<TabsPrimitive.TabsProps & React$1.RefAttributes<HTMLDivElement>>;
210
+ declare const TabsList: React$1.ForwardRefExoticComponent<Omit<TabsPrimitive.TabsListProps & React$1.RefAttributes<HTMLDivElement>, "ref"> & React$1.RefAttributes<HTMLDivElement>>;
211
+ declare const TabsTrigger: React$1.ForwardRefExoticComponent<Omit<TabsPrimitive.TabsTriggerProps & React$1.RefAttributes<HTMLButtonElement>, "ref"> & React$1.RefAttributes<HTMLButtonElement>>;
212
+ declare const TabsContent: React$1.ForwardRefExoticComponent<Omit<TabsPrimitive.TabsContentProps & React$1.RefAttributes<HTMLDivElement>, "ref"> & React$1.RefAttributes<HTMLDivElement>>;
213
+
214
+ declare const Checkbox: React$1.ForwardRefExoticComponent<Omit<CheckboxPrimitive.CheckboxProps & React$1.RefAttributes<HTMLButtonElement>, "ref"> & React$1.RefAttributes<HTMLButtonElement>>;
215
+
216
+ declare const Switch: React$1.ForwardRefExoticComponent<Omit<SwitchPrimitives.SwitchProps & React$1.RefAttributes<HTMLButtonElement>, "ref"> & React$1.RefAttributes<HTMLButtonElement>>;
217
+
218
+ declare const Collapsible: React$1.ForwardRefExoticComponent<CollapsiblePrimitive.CollapsibleProps & React$1.RefAttributes<HTMLDivElement>>;
219
+ declare const CollapsibleTrigger: React$1.ForwardRefExoticComponent<CollapsiblePrimitive.CollapsibleTriggerProps & React$1.RefAttributes<HTMLButtonElement>>;
220
+ declare const CollapsibleContent: React$1.ForwardRefExoticComponent<CollapsiblePrimitive.CollapsibleContentProps & React$1.RefAttributes<HTMLDivElement>>;
221
+
222
+ declare const Sheet: React$1.FC<DialogPrimitive.DialogProps>;
223
+ declare const SheetTrigger: React$1.ForwardRefExoticComponent<DialogPrimitive.DialogTriggerProps & React$1.RefAttributes<HTMLButtonElement>>;
224
+ declare const SheetClose: React$1.ForwardRefExoticComponent<DialogPrimitive.DialogCloseProps & React$1.RefAttributes<HTMLButtonElement>>;
225
+ declare const SheetPortal: React$1.FC<DialogPrimitive.DialogPortalProps>;
226
+ declare const SheetOverlay: React$1.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogOverlayProps & React$1.RefAttributes<HTMLDivElement>, "ref"> & React$1.RefAttributes<HTMLDivElement>>;
227
+ declare const sheetVariants: (props?: ({
228
+ side?: "left" | "top" | "bottom" | "right" | null | undefined;
229
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
230
+ interface SheetContentProps extends React$1.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>, VariantProps<typeof sheetVariants> {
231
+ }
232
+ declare const SheetContent: React$1.ForwardRefExoticComponent<SheetContentProps & React$1.RefAttributes<HTMLDivElement>>;
233
+ declare const SheetHeader: {
234
+ ({ className, ...props }: React$1.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
235
+ displayName: string;
236
+ };
237
+ declare const SheetFooter: {
238
+ ({ className, ...props }: React$1.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
239
+ displayName: string;
240
+ };
241
+ declare const SheetTitle: React$1.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogTitleProps & React$1.RefAttributes<HTMLHeadingElement>, "ref"> & React$1.RefAttributes<HTMLHeadingElement>>;
242
+ declare const SheetDescription: React$1.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogDescriptionProps & React$1.RefAttributes<HTMLParagraphElement>, "ref"> & React$1.RefAttributes<HTMLParagraphElement>>;
243
+
244
+ interface TextareaProps extends React$1.TextareaHTMLAttributes<HTMLTextAreaElement> {
245
+ }
246
+ declare const Textarea: React$1.ForwardRefExoticComponent<TextareaProps & React$1.RefAttributes<HTMLTextAreaElement>>;
247
+
248
+ declare const TooltipProvider: React$1.FC<TooltipPrimitive.TooltipProviderProps>;
249
+ declare const Tooltip: React$1.FC<TooltipPrimitive.TooltipProps>;
250
+ declare const TooltipTrigger: React$1.ForwardRefExoticComponent<TooltipPrimitive.TooltipTriggerProps & React$1.RefAttributes<HTMLButtonElement>>;
251
+ declare const TooltipContent: React$1.ForwardRefExoticComponent<Omit<TooltipPrimitive.TooltipContentProps & React$1.RefAttributes<HTMLDivElement>, "ref"> & React$1.RefAttributes<HTMLDivElement>>;
252
+
253
+ declare const Avatar: React$1.ForwardRefExoticComponent<Omit<AvatarPrimitive.AvatarProps & React$1.RefAttributes<HTMLSpanElement>, "ref"> & React$1.RefAttributes<HTMLSpanElement>>;
254
+ declare const AvatarImage: React$1.ForwardRefExoticComponent<Omit<AvatarPrimitive.AvatarImageProps & React$1.RefAttributes<HTMLImageElement>, "ref"> & React$1.RefAttributes<HTMLImageElement>>;
255
+ declare const AvatarFallback: React$1.ForwardRefExoticComponent<Omit<AvatarPrimitive.AvatarFallbackProps & React$1.RefAttributes<HTMLSpanElement>, "ref"> & React$1.RefAttributes<HTMLSpanElement>>;
256
+
257
+ interface PageShellProps extends React$1.HTMLAttributes<HTMLDivElement> {
258
+ maxWidth?: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full';
259
+ }
260
+ declare function PageShell({ maxWidth, className, children, ...props }: PageShellProps): react_jsx_runtime.JSX.Element;
261
+
262
+ interface StatItem {
263
+ label: string;
264
+ value: string | number;
265
+ color?: 'default' | 'green' | 'yellow' | 'red' | 'blue';
266
+ alert?: boolean;
267
+ }
268
+ interface StatsGridProps extends React$1.HTMLAttributes<HTMLDivElement> {
269
+ stats: StatItem[];
270
+ columns?: 2 | 3 | 4 | 6;
271
+ }
272
+ declare function StatsGrid({ stats, columns, className, ...props }: StatsGridProps): react_jsx_runtime.JSX.Element;
273
+
274
+ interface SectionCardProps extends React$1.HTMLAttributes<HTMLDivElement> {
275
+ icon?: React$1.ReactNode;
276
+ title: string;
277
+ count?: number;
278
+ defaultOpen?: boolean;
279
+ collapsible?: boolean;
280
+ }
281
+ declare function SectionCard({ icon, title, count, defaultOpen, collapsible, className, children, ...props }: SectionCardProps): react_jsx_runtime.JSX.Element;
282
+
283
+ interface EmptyStateProps extends React$1.HTMLAttributes<HTMLDivElement> {
284
+ icon?: React$1.ReactNode;
285
+ title: string;
286
+ description?: string;
287
+ action?: React$1.ReactNode;
288
+ }
289
+ declare function EmptyState({ icon, title, description, action, className, ...props }: EmptyStateProps): react_jsx_runtime.JSX.Element;
290
+
291
+ interface SearchBarProps extends Omit<React$1.InputHTMLAttributes<HTMLInputElement>, 'onChange'> {
292
+ value: string;
293
+ onChange: (value: string) => void;
294
+ onClear?: () => void;
295
+ }
296
+ declare function SearchBar({ value, onChange, onClear, className, placeholder, ...props }: SearchBarProps): react_jsx_runtime.JSX.Element;
297
+
298
+ interface DataRowProps extends React$1.HTMLAttributes<HTMLDivElement> {
299
+ status?: 'green' | 'yellow' | 'red' | 'gray';
300
+ primary: string;
301
+ secondary?: string;
302
+ trailing?: React$1.ReactNode;
303
+ }
304
+ declare function DataRow({ status, primary, secondary, trailing, className, ...props }: DataRowProps): react_jsx_runtime.JSX.Element;
305
+
306
+ declare const fadeInUp: {
307
+ initial: {
308
+ opacity: number;
309
+ y: number;
310
+ };
311
+ animate: {
312
+ opacity: number;
313
+ y: number;
314
+ };
315
+ transition: {
316
+ duration: number;
317
+ ease: number[];
318
+ };
319
+ };
320
+ declare const fadeInDown: {
321
+ initial: {
322
+ opacity: number;
323
+ y: number;
324
+ };
325
+ animate: {
326
+ opacity: number;
327
+ y: number;
328
+ };
329
+ transition: {
330
+ duration: number;
331
+ ease: number[];
332
+ };
333
+ };
334
+ declare const staggerContainer: {
335
+ initial: {};
336
+ animate: {
337
+ transition: {
338
+ staggerChildren: number;
339
+ };
340
+ };
341
+ };
342
+ declare const staggerItem: {
343
+ initial: {
344
+ opacity: number;
345
+ y: number;
346
+ };
347
+ animate: {
348
+ opacity: number;
349
+ y: number;
350
+ transition: {
351
+ duration: number;
352
+ };
353
+ };
354
+ };
355
+ declare const pageTransition: {
356
+ initial: {
357
+ opacity: number;
358
+ };
359
+ animate: {
360
+ opacity: number;
361
+ };
362
+ exit: {
363
+ opacity: number;
364
+ };
365
+ transition: {
366
+ duration: number;
367
+ };
368
+ };
369
+ declare const hoverScale: {
370
+ whileHover: {
371
+ scale: number;
372
+ };
373
+ whileTap: {
374
+ scale: number;
375
+ };
376
+ transition: {
377
+ type: string;
378
+ stiffness: number;
379
+ damping: number;
380
+ };
381
+ };
382
+ declare const hoverLift: {
383
+ whileHover: {
384
+ y: number;
385
+ };
386
+ transition: {
387
+ type: string;
388
+ stiffness: number;
389
+ damping: number;
390
+ };
391
+ };
392
+ declare const springBounce: {
393
+ type: "spring";
394
+ stiffness: number;
395
+ damping: number;
396
+ };
397
+ declare const easeSmooth: readonly [0.25, 0.46, 0.45, 0.94];
398
+
399
+ interface FadeInProps extends React$1.HTMLAttributes<HTMLDivElement> {
400
+ delay?: number;
401
+ direction?: 'up' | 'left';
402
+ }
403
+ declare function FadeIn({ children, className, delay, direction, ...props }: FadeInProps): react_jsx_runtime.JSX.Element;
404
+
198
405
  declare function Footer(): react_jsx_runtime.JSX.Element;
199
406
 
200
- export { AnimatedTooltip, Badge, type BadgeProps, Button, type ButtonProps, Calendar, CalendarDayButton, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, type ChartConfig, ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, DatePicker, DateTimePicker, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, FlipWords, Footer, HeroHighlight, Highlight, HoverCard, HoverCardDescription, HoverCardTitle, HoverEffect, Input, type InputProps, Label, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, TimePicker, badgeVariants, buttonVariants };
407
+ export { AnimatedTooltip, Avatar, AvatarFallback, AvatarImage, Badge, type BadgeProps, Button, type ButtonProps, Calendar, CalendarDayButton, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, type ChartConfig, ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, Checkbox, Collapsible, CollapsibleContent, CollapsibleTrigger, DataRow, type DataRowProps, DatePicker, DateTimePicker, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, EmptyState, type EmptyStateProps, FadeIn, type FadeInProps, FlipWords, Footer, HeroHighlight, Highlight, HoverCard, HoverCardDescription, HoverCardTitle, HoverEffect, Input, type InputProps, Label, PageShell, type PageShellProps, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, SearchBar, type SearchBarProps, SectionCard, type SectionCardProps, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, Skeleton, type StatItem, StatsGrid, type StatsGridProps, Switch, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, type TextareaProps, TimePicker, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, badgeVariants, buttonVariants, easeSmooth, fadeInDown, fadeInUp, hoverLift, hoverScale, pageTransition, springBounce, staggerContainer, staggerItem };