diff --git a/app/api/github/releases/route.ts b/app/api/github/releases/route.ts index a736fd3..f6fa8c8 100644 --- a/app/api/github/releases/route.ts +++ b/app/api/github/releases/route.ts @@ -120,8 +120,10 @@ export async function GET(request: Request) { const { searchParams } = new URL(request.url) const repo = searchParams.get('repo') // Optional: filter by specific repo - const token = await getGithubToken() - const repositories = await getConfiguredRepositories() + const [token, repositories] = await Promise.all([ + getGithubToken(), + getConfiguredRepositories(), + ]) try { const reposToFetch = repo diff --git a/app/games/opengraph-image.tsx b/app/games/opengraph-image.tsx index ccf8bdd..8f9548d 100644 --- a/app/games/opengraph-image.tsx +++ b/app/games/opengraph-image.tsx @@ -1,6 +1,5 @@ import { OG_CONFIGS, OG_CONTENT_TYPE, OG_SIZE, makeOGImage } from '../_og/image-generator' -export const runtime = 'edge' export const alt = 'NodeByte Game Server Hosting — Minecraft, Rust, Hytale & more' export const size = OG_SIZE export const contentType = OG_CONTENT_TYPE diff --git a/app/games/page.tsx b/app/games/page.tsx index bc2a1ef..04feb13 100644 --- a/app/games/page.tsx +++ b/app/games/page.tsx @@ -85,6 +85,7 @@ export default async function GamesPage() { src={game.banner} alt={game.name} fill + sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw" className="object-cover transition-transform duration-300 group-hover:scale-105" />
@@ -124,7 +125,7 @@ export default async function GamesPage() { {/* Features */}
diff --git a/app/opengraph-image.tsx b/app/opengraph-image.tsx index 4372e68..efcec49 100644 --- a/app/opengraph-image.tsx +++ b/app/opengraph-image.tsx @@ -1,6 +1,5 @@ import { OG_CONFIGS, OG_CONTENT_TYPE, OG_SIZE, makeOGImage } from './_og/image-generator' -export const runtime = 'edge' export const alt = 'NodeByte Hosting — Game Servers & VPS' export const size = OG_SIZE export const contentType = OG_CONTENT_TYPE diff --git a/app/page.tsx b/app/page.tsx index 9485ad0..144978f 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,3 +1,4 @@ +import { Metadata } from "next" import { Hero } from "@/packages/ui/components/Layouts/Home/hero" import { Features } from "@/packages/ui/components/Layouts/Home/features" import { About } from "@/packages/ui/components/Layouts/Home/about" @@ -5,6 +6,11 @@ import { Services } from "@/packages/ui/components/Layouts/Home/services" import { FAQ } from "@/packages/ui/components/Layouts/Home/faq" import { ScrollToHash } from "@/packages/ui/components/scroll-to-hash" +export const metadata: Metadata = { + title: "Home", + description: "Fast, reliable, and secure hosting for game servers and VPS. Instant deployment, enterprise DDoS protection, NVMe SSD storage, and 24/7 expert support.", +} + export default function Home() { return ( <> diff --git a/app/twitter-image.tsx b/app/twitter-image.tsx index 4372e68..efcec49 100644 --- a/app/twitter-image.tsx +++ b/app/twitter-image.tsx @@ -1,6 +1,5 @@ import { OG_CONFIGS, OG_CONTENT_TYPE, OG_SIZE, makeOGImage } from './_og/image-generator' -export const runtime = 'edge' export const alt = 'NodeByte Hosting — Game Servers & VPS' export const size = OG_SIZE export const contentType = OG_CONTENT_TYPE diff --git a/app/vps/opengraph-image.tsx b/app/vps/opengraph-image.tsx index 7c186e1..a7a872c 100644 --- a/app/vps/opengraph-image.tsx +++ b/app/vps/opengraph-image.tsx @@ -1,6 +1,5 @@ import { OG_CONFIGS, OG_CONTENT_TYPE, OG_SIZE, makeOGImage } from '../_og/image-generator' -export const runtime = 'edge' export const alt = 'NodeByte VPS Hosting — AMD & Intel KVM VPS' export const size = OG_SIZE export const contentType = OG_CONTENT_TYPE diff --git a/app/vps/twitter-image.tsx b/app/vps/twitter-image.tsx index 7c186e1..a7a872c 100644 --- a/app/vps/twitter-image.tsx +++ b/app/vps/twitter-image.tsx @@ -1,6 +1,5 @@ import { OG_CONFIGS, OG_CONTENT_TYPE, OG_SIZE, makeOGImage } from '../_og/image-generator' -export const runtime = 'edge' export const alt = 'NodeByte VPS Hosting — AMD & Intel KVM VPS' export const size = OG_SIZE export const contentType = OG_CONTENT_TYPE diff --git a/package.json b/package.json index d645779..e49e1de 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,8 @@ "postinstall": "git submodule update --init --recursive --remote", "translate": "bun run scripts/translate.ts", "translate:force": "bun run scripts/translate.ts --force", - "translate:dry": "bun run scripts/translate.ts --dry-run" + "translate:dry": "bun run scripts/translate.ts --dry-run", + "doctor": "npx react-doctor@latest" }, "dependencies": { "@hookform/resolvers": "^3.10.0", diff --git a/packages/changelog/components/changelog-card.tsx b/packages/changelog/components/changelog-card.tsx index 305d793..8d5fc10 100644 --- a/packages/changelog/components/changelog-card.tsx +++ b/packages/changelog/components/changelog-card.tsx @@ -56,23 +56,17 @@ const TYPE_LABELS: Record = { export function ChangelogCard({ release, translations, isLatest, isLinked, className }: ChangelogCardProps) { const [showAssets, setShowAssets] = useState(false) - const [expanded, setExpanded] = useState(isLinked ?? false) const [linkCopied, setLinkCopied] = useState(false) + const [userExpanded, setUserExpanded] = useState(false) const summary = extractSummary(release.body) const hasLongBody = (release.body?.length || 0) > 300 const typeColor = TYPE_COLORS[release.type || 'improvement'] const publishedDate = new Date(release.published_at || release.created_at) - // Create a unique anchor ID for this release const anchorId = `${release.repository.name}-${release.tag_name}` - // Expand when linked to directly - useEffect(() => { - if (isLinked) { - setExpanded(true) - } - }, [isLinked]) + const expanded = userExpanded || (isLinked ?? false) const handleCopyLink = async () => { const url = `${window.location.origin}${window.location.pathname}#${anchorId}` @@ -111,6 +105,7 @@ export function ChangelogCard({ release, translations, isLatest, isLinked, class - -
- {/* First page */} - {currentPage > 2 && ( - <> - - {currentPage > 3 && ( - ... - )} - - )} - - {/* Pages around current */} - {Array.from({ length: totalPages }, (_, i) => i + 1) - .filter(page => { - if (totalPages <= 5) return true - return Math.abs(page - currentPage) <= 1 - }) - .map(page => ( - - ))} - - {/* Last page */} - {currentPage < totalPages - 1 && ( - <> - {currentPage < totalPages - 2 && ( - ... - )} - - - )} -
- - - - )} + )} diff --git a/packages/changelog/components/changelog-pagination.tsx b/packages/changelog/components/changelog-pagination.tsx new file mode 100644 index 0000000..a16e0dd --- /dev/null +++ b/packages/changelog/components/changelog-pagination.tsx @@ -0,0 +1,93 @@ +"use client" + +import { ChevronLeft, ChevronRight } from "lucide-react" +import { Button } from "@/packages/ui/components/ui/button" + +interface ChangelogPaginationProps { + currentPage: number + totalPages: number + onPageChange: (page: number) => void + translations: { + previous: string + next: string + } +} + +export function ChangelogPagination({ currentPage, totalPages, onPageChange, translations }: ChangelogPaginationProps) { + if (totalPages <= 1) return null + + return ( +
+ + +
+ {currentPage > 2 && ( + <> + + {currentPage > 3 && ( + ... + )} + + )} + + {Array.from({ length: totalPages }, (_, i) => i + 1) + .filter(page => { + if (totalPages <= 5) return true + return Math.abs(page - currentPage) <= 1 + }) + .map(page => ( + + ))} + + {currentPage < totalPages - 1 && ( + <> + {currentPage < totalPages - 2 && ( + ... + )} + + + )} +
+ + +
+ ) +} diff --git a/packages/changelog/components/changelog-search.tsx b/packages/changelog/components/changelog-search.tsx index 1958097..480d8d9 100644 --- a/packages/changelog/components/changelog-search.tsx +++ b/packages/changelog/components/changelog-search.tsx @@ -29,6 +29,7 @@ export function ChangelogSearch({ /> {value && (