File size: 3,817 Bytes
c10f8f8
 
 
 
 
de2f961
c10f8f8
 
 
 
 
 
 
 
 
8bce833
c10f8f8
 
 
de2f961
 
 
c10f8f8
 
de2f961
c10f8f8
de2f961
 
 
8bce833
c10f8f8
 
 
8bce833
 
c10f8f8
 
 
 
 
 
 
 
 
 
8bce833
 
 
c10f8f8
 
 
 
 
 
de2f961
 
c10f8f8
 
1cb3dcc
 
dd2ee70
ddb7f1c
c10f8f8
 
 
 
 
 
1cb3dcc
ddb7f1c
c10f8f8
1cb3dcc
ddb7f1c
c10f8f8
 
 
 
de2f961
 
 
 
c10f8f8
8bce833
 
 
 
 
6cca3b1
8bce833
 
 
 
6cca3b1
8bce833
 
de2f961
 
5994edd
 
 
8bce833
 
 
 
 
 
 
 
 
 
 
 
5994edd
 
 
 
 
c10f8f8
 
 
 
 
 
 
 
 
de2f961
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/* eslint-disable @typescript-eslint/no-explicit-any */
import type { Metadata, Viewport } from "next";
import { Inter, PT_Sans } from "next/font/google";
import { cookies } from "next/headers";
import Script from "next/script";

import "@/assets/globals.css";
import { Toaster } from "@/components/ui/sonner";
import MY_TOKEN_KEY from "@/lib/get-cookie-name";
import { apiServer } from "@/lib/api";
import IframeDetector from "@/components/iframe-detector";
import AppContext from "@/components/contexts/app-context";
import TanstackContext from "@/components/contexts/tanstack-query-context";
import { LoginProvider } from "@/components/contexts/login-context";
import { ProProvider } from "@/components/contexts/pro-context";
import { generateSEO, generateStructuredData } from "@/lib/seo";

const inter = Inter({
  variable: "--font-inter-sans",
  subsets: ["latin"],
});

const ptSans = PT_Sans({
  variable: "--font-ptSans-mono",
  subsets: ["latin"],
  weight: ["400", "700"],
});

export const metadata: Metadata = {
  ...generateSEO({
    title: "DeepSite | Build with AI ✨",
    description:
      "DeepSite is a web development tool that helps you build websites with AI, no code required. Let's deploy your website with DeepSite and enjoy the magic of AI.",
    path: "/",
  }),
  appleWebApp: {
    capable: true,
    title: "DeepSite",
    statusBarStyle: "black-translucent",
  },
  icons: {
    icon: "/logo.svg",
    shortcut: "/logo.svg",
    apple: "/logo.svg",
  },
  verification: {
    google: process.env.GOOGLE_SITE_VERIFICATION,
  },
};

export const viewport: Viewport = {
  initialScale: 1,
  maximumScale: 1,
  themeColor: "#000000",
};

async function getMe() {
  const cookieStore = await cookies();
  const cookieName = MY_TOKEN_KEY();
  const token = cookieStore.get(cookieName)?.value;

  if (!token) return { user: null, projects: [], errCode: null };
  try {
    const res = await apiServer.get("/me", {
      headers: {
        Authorization: `Bearer ${token}`,
      },
    });
    console.log("✅ [Server] User authenticated:", res.data.user?.name);
    return { user: res.data.user, projects: res.data.projects, errCode: null };
  } catch (err: any) {
    console.error("❌ [Server] Auth error:", err.status, err.message);
    return { user: null, projects: [], errCode: err.status };
  }
}

export default async function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  const data = await getMe();

  // Generate structured data
  const structuredData = generateStructuredData("WebApplication", {
    name: "DeepSite",
    description: "Build websites with AI, no code required",
    url: "https://huggingface.co/deepsite",
  });

  const organizationData = generateStructuredData("Organization", {
    name: "DeepSite",
    url: "https://huggingface.co/deepsite",
  });

  return (
    <html lang="en">
      <body
        className={`${inter.variable} ${ptSans.variable} antialiased bg-black dark h-[100dvh] overflow-hidden`}
      >
        <script
          type="application/ld+json"
          dangerouslySetInnerHTML={{
            __html: JSON.stringify(structuredData),
          }}
        />
        <script
          type="application/ld+json"
          dangerouslySetInnerHTML={{
            __html: JSON.stringify(organizationData),
          }}
        />
        <Script
          defer
          data-domain="huggingface.co/deepsite"
          src="https://plausible.io/js/script.js"
        />
        <IframeDetector />
        <Toaster richColors position="bottom-center" />
        <TanstackContext>
          <AppContext me={data}>
            <LoginProvider>
              <ProProvider>{children}</ProProvider>
            </LoginProvider>
          </AppContext>
        </TanstackContext>
      </body>
    </html>
  );
}