diff --git a/src/app/(dashboard)/layout.tsx b/src/app/(dashboard)/layout.tsx index 49af1dd..a21ac47 100644 --- a/src/app/(dashboard)/layout.tsx +++ b/src/app/(dashboard)/layout.tsx @@ -3,6 +3,7 @@ import { Toaster } from "sonner" import Navbar from "@/components/layout/navbar" import AppSidebar from "@/components/layout/sidebar" import { SidebarProvider } from "@/components/ui/sidebar" +import { getI18n } from "@/i18n/server" import { auth } from "@/lib/auth" export default async function LayoutDashboard({ @@ -11,10 +12,14 @@ export default async function LayoutDashboard({ children: React.ReactNode }) { const session = await auth() + const { dictionary } = await getI18n() return ( - +
{children}
diff --git a/src/app/forbidden/page.tsx b/src/app/forbidden/page.tsx index 681b3af..288cb91 100644 --- a/src/app/forbidden/page.tsx +++ b/src/app/forbidden/page.tsx @@ -1,11 +1,15 @@ import Link from "next/link" -export default function ForbiddenPage() { +import { getI18n } from "@/i18n/server" + +export default async function ForbiddenPage() { + const { dictionary } = await getI18n() + const copy = dictionary.common.forbidden return (
-

Acceso denegado

-

No tienes permisos para acceder a esta sección.

- Volver al inicio +

{copy.title}

+

{copy.description}

+ {copy.homeLink}
) } diff --git a/src/components/auth/logout.tsx b/src/components/auth/logout.tsx index b93f2c6..d7b05c5 100644 --- a/src/components/auth/logout.tsx +++ b/src/components/auth/logout.tsx @@ -1,8 +1,13 @@ import { Button } from "@/components/ui/button" +import type { Dictionary } from "@/i18n/dictionaries" import { signOut } from "@/lib/auth" import { SIGN_IN_URL } from "@/lib/constants" -export function SignOut() { +type SignOutProps = { + copy: Dictionary["layout"]["logout"] +} + +export function SignOut({ copy }: SignOutProps) { return (
{ @@ -11,7 +16,7 @@ export function SignOut() { }} >
) diff --git a/src/components/common/pageheader.tsx b/src/components/common/pageheader.tsx index 0844bcc..c3b3c06 100644 --- a/src/components/common/pageheader.tsx +++ b/src/components/common/pageheader.tsx @@ -3,6 +3,7 @@ import Link from "next/link" import Search from "@/components/common/search" import { Button } from "@/components/ui/button" +import { getI18n } from "@/i18n/server" interface PageHeaderProps { title?: string @@ -11,17 +12,21 @@ interface PageHeaderProps { data: unknown[] } -export default function PageHeader({ +export default async function PageHeader({ title, link, search, data, }: PageHeaderProps) { + const { dictionary } = await getI18n() return (

{title}

-
{link && (
diff --git a/src/components/common/pagination.client.tsx b/src/components/common/pagination.client.tsx new file mode 100644 index 0000000..b4ff8e8 --- /dev/null +++ b/src/components/common/pagination.client.tsx @@ -0,0 +1,101 @@ +"use client" + +import { usePathname, useRouter, useSearchParams } from "next/navigation" + +import { + Pagination, + PaginationContent, + PaginationItem, + PaginationLink, + PaginationNext, + PaginationPrevious, +} from "@/components/ui/pagination" +import type { Dictionary } from "@/i18n/dictionaries" + +type PaginationCopy = Dictionary["common"]["pagination"] + +type PaginationClientProps = { + copy: PaginationCopy + totalPages: number +} + +export function PaginationClient({ copy, totalPages }: PaginationClientProps) { + const pathname = usePathname() + const searchParams = useSearchParams() + const router = useRouter() + const currentPage = Number(searchParams.get("page")) || 1 + + const createPageURL = (pageNumber: number | string) => { + const params = new URLSearchParams(searchParams) + params.set("page", pageNumber.toString()) + router.push(`${pathname}?${params.toString()}`) + return `${pathname}?${params.toString()}` + } + + const getPageNumbers = () => { + let start = Math.max(1, currentPage - 1) + let end = Math.min(totalPages, currentPage + 1) + + // Always try to show 3 pages if possible + if (end - start < 2) { + if (start === 1) { + end = Math.min(totalPages, start + 2) + } else if (end === totalPages) { + start = Math.max(1, end - 2) + } + } + + const pages = [] + for (let i = start; i <= end; i++) { + pages.push(i) + } + return pages + } + + const pageNumbers = getPageNumbers() + + return ( +
+
+ {copy.summaryPrefix} {currentPage} {copy.summarySeparator} {totalPages} +
+
+ + + {currentPage > 1 && ( + + createPageURL(currentPage - 1)} + className="cursor-pointer" + > + {copy.previous} + + + )} + {pageNumbers.map((page) => ( + + createPageURL(page)} + isActive={page === currentPage} + className="cursor-pointer" + > + {page} + + + ))} + {currentPage < totalPages && ( + + createPageURL(currentPage + 1)} + className="cursor-pointer" + > + {copy.next} + + + )} + + +
+
+ ) +} diff --git a/src/components/common/pagination.tsx b/src/components/common/pagination.tsx index 7e1bfc7..8bcdc4d 100755 --- a/src/components/common/pagination.tsx +++ b/src/components/common/pagination.tsx @@ -1,97 +1,18 @@ -"use client" +import { getI18n } from "@/i18n/server" -import { usePathname, useRouter, useSearchParams } from "next/navigation" +import { PaginationClient } from "./pagination.client" -import { - Pagination, - PaginationContent, - PaginationItem, - PaginationLink, - PaginationNext, - PaginationPrevious, -} from "@/components/ui/pagination" - -export default function PaginationButtons({ +export default async function PaginationButtons({ totalPages, }: { totalPages: number }) { - const pathname = usePathname() - const searchParams = useSearchParams() - const router = useRouter() - const currentPage = Number(searchParams.get("page")) || 1 - - const createPageURL = (pageNumber: number | string) => { - const params = new URLSearchParams(searchParams) - params.set("page", pageNumber.toString()) - router.push(`${pathname}?${params.toString()}`) - return `${pathname}?${params.toString()}` - } - - const getPageNumbers = () => { - let start = Math.max(1, currentPage - 1) - let end = Math.min(totalPages, currentPage + 1) - - // Always try to show 3 pages if possible - if (end - start < 2) { - if (start === 1) { - end = Math.min(totalPages, start + 2) - } else if (end === totalPages) { - start = Math.max(1, end - 2) - } - } - - const pages = [] - for (let i = start; i <= end; i++) { - pages.push(i) - } - return pages - } - - const pageNumbers = getPageNumbers() + const { dictionary } = await getI18n() return ( -
-
- Showing page {currentPage} of {totalPages} -
-
- - - {currentPage > 1 && ( - - createPageURL(currentPage - 1)} - className="cursor-pointer" - > - Previous - - - )} - {pageNumbers.map((page) => ( - - createPageURL(page)} - isActive={page === currentPage} - className="cursor-pointer" - > - {page} - - - ))} - {currentPage < totalPages && ( - - createPageURL(currentPage + 1)} - className="cursor-pointer" - > - Next - - - )} - - -
-
+ ) } diff --git a/src/components/common/search.tsx b/src/components/common/search.tsx index b7213f5..39552b5 100755 --- a/src/components/common/search.tsx +++ b/src/components/common/search.tsx @@ -5,17 +5,23 @@ import { usePathname, useRouter, useSearchParams } from "next/navigation" import { useEffect, useRef, useState } from "react" import { useDebouncedCallback } from "use-debounce" +import type { Dictionary } from "@/i18n/dictionaries" + import { Input } from "../ui/input" +type SearchCopy = Dictionary["common"]["search"] + interface SearchProps { + copy: SearchCopy paramKey?: string placeholder?: string [x: string]: unknown } export default function Search({ + copy, paramKey = "search", - placeholder = "Search...", + placeholder = copy.placeholder, ...props }: SearchProps) { const pathname = usePathname() @@ -73,7 +79,7 @@ export default function Search({ ref={inputRef} type="text" role="searchbox" - aria-label="Buscar" + aria-label={copy.label} placeholder={placeholder} value={search} onChange={(e) => { @@ -86,7 +92,7 @@ export default function Search({ {search && ( @@ -51,18 +62,18 @@ export default function AddMenu() { className="flex cursor-pointer items-center gap-2" passHref > - Import + {copy.import} {items.map((item) => ( - + - {item.name} + {copy[item.key]} ))} @@ -70,7 +81,7 @@ export default function AddMenu() { <> - + )} diff --git a/src/components/layout/navbar.tsx b/src/components/layout/navbar.tsx index d527145..d5c95be 100644 --- a/src/components/layout/navbar.tsx +++ b/src/components/layout/navbar.tsx @@ -28,7 +28,10 @@ export default async function Navbar() {