Add lib/tenant.ts as the single source of truth for multi- vs single-tenant deployment. Gate space creation (server + signup UI), add open-join to the one space, hide the marketing shell, and route brand name + base URL through config. Also commit the _migrations_applied table into the canonical schema so a fresh instance is reproducible from schema.sql alone. - lib/tenant.ts: resolveTenantConfig (pure) + tenantConfig() + appBaseUrl() - lib/auth-actions.ts: createSpace refused when !allowSpaceCreation; joinSpace open-join resolves the configured/sole space with no invite code - proxy.ts: marketing paths redirect to /login when showMarketing is off - app/signup/page.tsx: single-tenant hides create/join chooser, brand=siteName - app/layout.tsx + 4 link builders: brand/base-URL via config (no hackerspace.sh literal) - scripts/schema.sql: public._migrations_applied tracking table - .env.example: documented single-tenant + first-admin bootstrap vars - package.json: pnpm setup
36 lines
933 B
TypeScript
36 lines
933 B
TypeScript
import type { Metadata } from 'next'
|
|
import { Geist, Geist_Mono } from 'next/font/google'
|
|
import { Toaster } from 'sonner'
|
|
import { tenantConfig } from '@/lib/tenant'
|
|
import './globals.css'
|
|
|
|
const _geist = Geist({ subsets: ["latin"] });
|
|
const _geistMono = Geist_Mono({ subsets: ["latin"] });
|
|
|
|
const _tenant = tenantConfig()
|
|
|
|
export const metadata: Metadata = {
|
|
title: `${_tenant.siteName} — Manage Your Space`,
|
|
description: 'The operating system for hackerspaces: members, tasks, projects, ops, payments, and comms.',
|
|
icons: {
|
|
icon: [{ url: '/logo.svg', type: 'image/svg+xml' }],
|
|
apple: '/logo.svg',
|
|
shortcut: '/logo.svg',
|
|
},
|
|
}
|
|
|
|
export default function RootLayout({
|
|
children,
|
|
}: Readonly<{
|
|
children: React.ReactNode
|
|
}>) {
|
|
return (
|
|
<html lang="en">
|
|
<body className="font-sans antialiased">
|
|
{children}
|
|
<Toaster richColors position="bottom-right" />
|
|
</body>
|
|
</html>
|
|
)
|
|
}
|