import { sentryHandleError } from '~/lib/sentry'; import { useStore } from '@nanostores/react'; import type { LinksFunction, LoaderFunction } from '~/lib/remix-types'; import { json } from '~/lib/remix-types'; import { Links, Meta, Outlet, Scripts, ScrollRestoration, useRouteError, useLoaderData } from '@remix-run/react'; import tailwindReset from '@unocss/reset/tailwind-compat.css?url'; import { themeStore } from './lib/stores/theme'; import { stripIndents } from './utils/stripIndent'; import { createHead } from 'remix-island'; import { useEffect, useState } from 'react'; import { logStore } from './lib/stores/logs'; import { initializeAuth, userStore, isLoadingStore } from './lib/stores/auth'; import { initializeUserStores } from './lib/stores/user'; import { ToastContainer } from 'react-toastify'; import { Analytics } from '@vercel/analytics/remix'; import { AuthModal } from './components/auth/AuthModal'; import reactToastifyStyles from 'react-toastify/dist/ReactToastify.css?url'; import globalStyles from './styles/index.scss?url'; import xtermStyles from '@xterm/xterm/css/xterm.css?url'; import 'virtual:uno.css'; interface LoaderData { ENV: { SUPABASE_URL: string; SUPABASE_ANON_KEY: string; USE_SUPABASE?: string; }; } export const links: LinksFunction = () => [ { rel: 'icon', href: '/favicon.svg', type: 'image/svg+xml', }, { rel: 'stylesheet', href: reactToastifyStyles }, { rel: 'stylesheet', href: tailwindReset }, { rel: 'stylesheet', href: globalStyles }, { rel: 'stylesheet', href: xtermStyles }, { rel: 'preconnect', href: 'https://fonts.googleapis.com', }, { rel: 'preconnect', href: 'https://fonts.gstatic.com', crossOrigin: 'anonymous', }, { rel: 'stylesheet', href: 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap', }, ]; export const loader: LoaderFunction = async () => { const supabaseUrl = process.env.SUPABASE_URL as string; const supabaseAnonKey = process.env.SUPABASE_ANON_KEY as string; const useSupabase = process.env.USE_SUPABASE as string; console.log('useSupabase', useSupabase); return json({ ENV: { SUPABASE_URL: supabaseUrl, SUPABASE_ANON_KEY: supabaseAnonKey, USE_SUPABASE: useSupabase, }, }); }; const inlineThemeCode = stripIndents` setTutorialKitTheme(); function setTutorialKitTheme() { let theme = localStorage.getItem('bolt_theme'); if (!theme) { theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; } document.querySelector('html')?.setAttribute('data-theme', theme); } `; export const Head = createHead(() => ( <>