Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Next #66

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open

Next #66

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
/.pnp
.pnp.js
.yarn/install-state.gz
pnpm-lock.yaml

# contentlayer
.contentlayer

# testing
/coverage
Expand Down
4 changes: 2 additions & 2 deletions app/(developers)/api/og/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ export async function GET(req: NextRequest) {
if (!project) {
return NextResponse.json({'error': 'Project not found'}, { status: 400 });
}
const platformProject = await platforms.getPlatformProject(project.platform, project.slug);
const platformProject = await platforms.getPlatformProject(project);
return projectPageImage(coords, platformProject, fonts);
}

Expand All @@ -277,7 +277,7 @@ export async function GET(req: NextRequest) {
return NextResponse.json({'error': 'Page not found'}, { status: 400 });
}

const project = await platforms.getPlatformProject(page.project.platform, page.project.slug);
const project = await platforms.getPlatformProject(page.project);
const metadata = matter(page.content).data as DocsEntryMetadata;

const iconUrl: AssetLocation | null = metadata.hide_icon === true || !metadata.icon && !metadata.id ? null : await service.getAsset(slug, (metadata.icon || metadata.id)!, version);
Expand Down
2 changes: 1 addition & 1 deletion app/[locale]/(main)/(developers)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default async function ProjectLayout({params, children}: Readonly<{
setContextLocale(params.locale);

return (
<div className="flex flex-col w-full items-center mx-1 sm:mx-6">
<div className="flex flex-col w-full items-center mx-1 page-wrapper-ext">
<div className="max-w-5xl w-full">
{children}
</div>
Expand Down
2 changes: 1 addition & 1 deletion app/[locale]/(main)/about/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default function AboutLayout({params, children}: Readonly<{
const messages = useMessages();

return (
<div className="flex flex-col md:flex-row gap-4 w-full md:justify-center">
<div className="flex flex-col md:flex-row gap-4 w-full md:justify-center page-wrapper-ext">
<aside className="w-full md:w-64 flex-shrink-0 bg-muted rounded-md px-2 mb-2 md:mb-0">
<MetaDocsNavigation messages={messages['MetaDocsNavigation']} docsOnly={localPreview.isEnabled()}/>
</aside>
Expand Down
2 changes: 1 addition & 1 deletion app/[locale]/(main)/browse/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default function Browse({params, searchParams}: Properties) {

return (
<NuqsAdapter>
<div className="flex flex-col md:flex-row gap-4 w-full md:justify-center">
<div className="flex flex-col md:flex-row gap-4 w-full md:justify-center page-wrapper-ext">
<aside
className="px-1 md:p-1.5 md:pt-2 bg-muted rounded-md w-full md:w-64 mb-2 md:mb-0 flex-shrink-0 md:sticky md:top-20 md:h-[calc(100vh_-_8rem)]"
>
Expand Down
14 changes: 6 additions & 8 deletions app/[locale]/(main)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import {ReactNode} from "react";
import {setContextLocale} from "@/lib/locales/routing";
import { ReactNode } from "react";
import { setContextLocale } from "@/lib/locales/routing";

export default function LocaleLayout({params, children}: Readonly<{
export default function LocaleLayout({ params, children }: Readonly<{
params: { locale: string };
children: ReactNode;
}>) {
setContextLocale(params.locale);

return (
<div className="page-wrapper flex flex-1 min-h-[100vh] mx-4 sm:mx-2">
{children}
</div>
)
return <div className="flex flex-col min-h-screen mx-4 page-wrapper sm:mx-2">
{children}
</div>;
}
49 changes: 43 additions & 6 deletions app/[locale]/(main)/project/[slug]/[version]/[...path]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
import {Suspense} from "react";
import DocsEntryPage from "@/components/docs/DocsEntryPage";
import DocsLoadingSkeleton from "@/components/docs/DocsLoadingSkeleton";
import DocsEntryPage from "@/components/docs/body/DocsEntryPage";
import DocsLoadingSkeleton from "@/components/docs/body/DocsLoadingSkeleton";
import {Metadata, ResolvingMetadata} from "next";
import {setContextLocale} from "@/lib/locales/routing";
import service from "@/lib/service";
import {redirect} from "next/navigation";
import matter from "gray-matter";
import {DocsEntryMetadata} from "@/lib/docs/metadata";
import platforms from "@/lib/platforms";
import DocsInnerLayoutClient from "@/components/docs/layout/DocsInnerLayoutClient";
import DocsPageFooter from "@/components/docs/layout/DocsPageFooter";
import DocsNonContentRightSidebar from "@/components/docs/side/DocsNonContentRightSidebar";
import DocsContentRightSidebar from "@/components/docs/side/DocsContentRightSidebar";
import {NextIntlClientProvider} from "next-intl";
import {getMessages} from "next-intl/server";
import {pick} from "lodash";

export const dynamic = 'force-static';
export const fetchCache = 'force-cache';
Expand All @@ -20,7 +27,7 @@ export async function generateMetadata({params}: {
return {title: (await parent).title?.absolute};
}

const project = await platforms.getPlatformProject(page.project.platform, page.project.slug);
const project = await platforms.getPlatformProject(page.project);
const result = matter(page.content).data as DocsEntryMetadata;

return {
Expand All @@ -40,12 +47,42 @@ export default async function ProjectDocsPage({params}: {
}) {
setContextLocale(params.locale);

const projectData = await service.getBackendLayout(params.slug, params.version, params.locale);
if (!projectData) {
return redirect('/');
}

const page = await service.renderDocsPage(params.slug, params.path, params.version, params.locale);
if (!page) redirect(`/project/${params.slug}/docs`);

const messages = await getMessages();

return (
<Suspense fallback={<DocsLoadingSkeleton/>}>
<DocsEntryPage page={page} path={params.path} version={params.version}/>
</Suspense>
<DocsInnerLayoutClient project={page.project}
tree={projectData.tree}
version={params.version} locale={params.locale}
rightSidebar={
!page.content.metadata.hide_meta
? <DocsContentRightSidebar project={projectData.project}
metadata={page.content.metadata}
version={params.version}/>
: <NextIntlClientProvider messages={pick(messages, 'DocsNonContentRightSidebar')}>
<DocsNonContentRightSidebar headings={page.content.metadata._headings || []}/>
</NextIntlClientProvider>
}
footer={
<DocsPageFooter locale={params.locale} locales={projectData.project.locales}
version={params.version} versions={projectData.project.versions}
editUrl={page.edit_url} updatedAt={page.updated_at}
showHistory={page.content.metadata.history !== undefined}
slug={params.slug} path={params.path}
local={projectData.project.local}
/>
}
>
<Suspense fallback={<DocsLoadingSkeleton/>}>
<DocsEntryPage page={page}/>
</Suspense>
</DocsInnerLayoutClient>
)
}
78 changes: 52 additions & 26 deletions app/[locale]/(main)/project/[slug]/[version]/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,34 @@
import ProjectDocsBaseLayout from "@/components/docs/layout/ProjectDocsBaseLayout";
import DocsTree from "@/components/docs/tree/DocsTree";
import {ReactNode} from "react";
import {setContextLocale} from "@/lib/locales/routing";
import service from "@/lib/service";
import DocsLayoutClient from "@/components/docs/layout/DocsLayoutClient";
import {redirect} from "next/navigation";
import {NextIntlClientProvider, useTranslations} from "next-intl";
import {getMessages} from "next-intl/server";
import {pick} from "lodash";
import {NuqsAdapter} from "nuqs/adapters/next/app";
import RightSidebarContextProvider from "@/components/docs/side/RightSidebarContext";
import LeftSidebarContextProvider from "@/components/docs/side/LeftSidebarContext";
import {ErrorBoundary} from "react-error-boundary";
import {FileQuestionIcon, HouseIcon} from "lucide-react";
import {Button} from "@/components/ui/button";
import Link from "next/link";
import GitHubIcon from "@/components/ui/icons/GitHubIcon";
import {NavLink} from "@/components/navigation/link/NavLink";
import {ErrorBoundary} from "react-error-boundary";
import {useTranslations} from "next-intl";
import PrimaryButton from "@/components/ui/custom/PrimaryButton";
import {redirect} from "next/navigation";
import service from "@/lib/service";
import {NavLink} from "@/components/navigation/link/NavLink";

export const dynamic = 'force-static';
export const fetchCache = 'force-cache';

interface LayoutProps {
children: ReactNode;
params: {
slug: string;
version: string;
locale: string;
};
}

function getIssueCreationLink(repo: any) {
return `https://github.com/${repo}/issues/new`;
}
Expand All @@ -40,16 +53,16 @@ function DocsPageNotFoundError({issueURL}: { issueURL?: string }) {

<div className="inline-flex gap-4 mt-4">
{issueURL &&
<Button variant="secondary" asChild>
<Link href={issueURL} target="_blank">
<GitHubIcon className="mr-2 w-4 h-4"/>
{t('submit')}
</Link>
</Button>
<Button variant="secondary" asChild>
<Link href={issueURL} target="_blank">
<GitHubIcon className="mr-2 w-4 h-4"/>
{t('submit')}
</Link>
</Button>
}
<PrimaryButton asChild>
<NavLink href="/">
<HouseIcon className="mr-2 w-4 h-4" strokeWidth={2.5} />
<HouseIcon className="mr-2 w-4 h-4" strokeWidth={2.5}/>
{t('return')}
</NavLink>
</PrimaryButton>
Expand All @@ -58,20 +71,33 @@ function DocsPageNotFoundError({issueURL}: { issueURL?: string }) {
)
}

export default async function ProjectLayout({children, params}: Readonly<{
children: ReactNode;
params: { slug: string; version: string; locale: string }
}>) {
export default async function HomepageLayout({children, params}: LayoutProps) {
setContextLocale(params.locale);

const data = await service.getBackendLayout(params.slug, params.version, params.locale);
if (!data) redirect('/');
const messages = await getMessages();

const projectData = await service.getBackendLayout(params.slug, params.version, params.locale);
if (!projectData) {
return redirect('/');
}

return (
<ErrorBoundary fallback={<DocsPageNotFoundError issueURL={data.project.is_public ? getIssueCreationLink(data.project.source_repo) : undefined}/>} >
<ProjectDocsBaseLayout leftPanel={<DocsTree slug={params.slug} tree={data.tree} version={params.version} />}>
{children}
</ProjectDocsBaseLayout>
<ErrorBoundary fallback={
<DocsPageNotFoundError
issueURL={projectData.project.is_public ? getIssueCreationLink(projectData.project.source_repo) : undefined}
/>
}>
<NuqsAdapter>
<LeftSidebarContextProvider>
<RightSidebarContextProvider>
<NextIntlClientProvider messages={pick(messages, 'ProjectTypes', 'ProjectCategories', 'PageEditControls', 'DocsVersionSelector', 'DocsLanguageSelect')}>
<DocsLayoutClient title={projectData.project.name}>
{children}
</DocsLayoutClient>
</NextIntlClientProvider>
</RightSidebarContextProvider>
</LeftSidebarContextProvider>
</NuqsAdapter>
</ErrorBoundary>
)
}
);
}
Loading