index.tsx raw

   1  import Relay from '@/components/Relay'
   2  import RelayIcon from '@/components/RelayIcon'
   3  import PrimaryPageLayout from '@/layouts/PrimaryPageLayout'
   4  import { normalizeUrl, simplifyUrl } from '@/lib/url'
   5  import { usePrimaryPage } from '@/PageManager'
   6  import { useFavoriteRelays } from '@/providers/FavoriteRelaysProvider'
   7  import { useRelayAdmin } from '@/providers/RelayAdminProvider'
   8  import { TPageRef } from '@/types'
   9  import { Server, Shield } from 'lucide-react'
  10  import { forwardRef, lazy, Suspense, useMemo } from 'react'
  11  
  12  const RelayAdminPanel = lazy(() => import('./admin'))
  13  
  14  const RelayPage = forwardRef<TPageRef>(({ url }: { url?: string }, ref) => {
  15    const normalizedUrl = useMemo(() => (url ? normalizeUrl(url) : undefined), [url])
  16    const { isEmbedded, isAdmin, isLoading } = useRelayAdmin()
  17  
  18    const showAdmin = isEmbedded && isAdmin && !normalizedUrl
  19  
  20    return (
  21      <PrimaryPageLayout
  22        pageName="relay"
  23        titlebar={<RelayPageTitlebar url={normalizedUrl} showAdmin={showAdmin} />}
  24        displayScrollToTopButton
  25        ref={ref}
  26      >
  27        {normalizedUrl ? (
  28          <Relay url={normalizedUrl} />
  29        ) : showAdmin ? (
  30          <Suspense
  31            fallback={
  32              <div className="flex items-center justify-center py-12 text-muted-foreground">
  33                Loading admin...
  34              </div>
  35            }
  36          >
  37            <RelayAdminPanel />
  38          </Suspense>
  39        ) : isEmbedded && !isLoading ? (
  40          <div className="flex items-center justify-center py-12 text-muted-foreground">
  41            Log in as admin to access relay management.
  42          </div>
  43        ) : (
  44          <RelayList />
  45        )}
  46      </PrimaryPageLayout>
  47    )
  48  })
  49  RelayPage.displayName = 'RelayPage'
  50  export default RelayPage
  51  
  52  function RelayList() {
  53    const { favoriteRelays } = useFavoriteRelays()
  54    const { navigate } = usePrimaryPage()
  55  
  56    if (favoriteRelays.length === 0) {
  57      return (
  58        <div className="flex items-center justify-center py-12 text-muted-foreground">
  59          No relays configured.
  60        </div>
  61      )
  62    }
  63  
  64    return (
  65      <div className="p-3 space-y-1">
  66        {favoriteRelays.map((relay) => (
  67          <button
  68            key={relay}
  69            className="w-full flex items-center gap-3 p-3 rounded-lg clickable hover:bg-muted/50 transition-colors text-left"
  70            onClick={() => navigate('relay', { url: relay })}
  71          >
  72            <RelayIcon url={relay} />
  73            <div className="flex-1 truncate font-medium">{simplifyUrl(relay)}</div>
  74          </button>
  75        ))}
  76      </div>
  77    )
  78  }
  79  
  80  function RelayPageTitlebar({ url, showAdmin }: { url?: string; showAdmin?: boolean }) {
  81    return (
  82      <div className="flex items-center gap-2 px-3 h-full">
  83        {showAdmin ? <Shield /> : <Server />}
  84        <div className="text-lg font-semibold truncate">
  85          {showAdmin ? 'Relay Admin' : url ? simplifyUrl(url) : 'Relays'}
  86        </div>
  87      </div>
  88    )
  89  }
  90