layout.tsx 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import type { Metadata } from "next";
  2. import { Geist, Geist_Mono } from "next/font/google";
  3. import React from "react";
  4. import "./globals.scss";
  5. import { SignalRProvider } from '@/contexts/signalrProvider';
  6. import { AuthProvider } from "@/contexts/authProvider";
  7. import { MemberProvider } from "@/contexts/memberProvider";
  8. import { ConfigProvider } from "@/contexts/configProvider";
  9. import { getAccessToken, getSignalRCryptoUrl, getSignalRChatUrl } from "@/lib/utils/server";
  10. import { fetchConfig } from "@/lib/api/system";
  11. const geistSans = Geist({
  12. variable: "--font-geist-sans",
  13. subsets: ["latin"],
  14. });
  15. const geistMono = Geist_Mono({
  16. variable: "--font-geist-mono",
  17. subsets: ["latin"],
  18. });
  19. export async function generateMetadata(): Promise<Metadata> {
  20. const config = (await fetchConfig())?.data;
  21. return {
  22. title: config?.basic?.siteName ?? 'bitforum',
  23. description: config?.meta?.description ?? '',
  24. keywords: config?.meta?.keywords ?? '',
  25. authors: config?.meta?.author ? [{ name: config.meta.author }] : undefined,
  26. applicationName: config?.meta.applicationName,
  27. generator: config?.meta.generator,
  28. robots: config?.meta.robots
  29. };
  30. }
  31. export default async function RootLayout({
  32. children,
  33. }: Readonly<{
  34. children: React.ReactNode;
  35. }>) {
  36. const accessToken = await getAccessToken();
  37. const signalRCryptoUrl = await getSignalRCryptoUrl();
  38. const signalRChatUrl = await getSignalRChatUrl();
  39. const config = (await fetchConfig())?.data;
  40. return (
  41. <html lang="ko">
  42. <body className={`${geistSans.variable} ${geistMono.variable} antialiased`}>
  43. <SignalRProvider accessToken={accessToken} signalRCryptoUrl={signalRCryptoUrl} signalRChatUrl={signalRChatUrl}>
  44. <AuthProvider>
  45. <MemberProvider>
  46. <ConfigProvider initialConfig={config}>
  47. {children}
  48. </ConfigProvider>
  49. </MemberProvider>
  50. </AuthProvider>
  51. </SignalRProvider>
  52. </body>
  53. </html>
  54. );
  55. }