diff --git a/Makefile b/Makefile
index b9f50c6..c31e795 100644
--- a/Makefile
+++ b/Makefile
@@ -35,4 +35,7 @@ clean:
docker image prune -f
ui:
- $(COMPOSE) exec $(SERVICE_NAME) npx shadcn@latest add $(component)
\ No newline at end of file
+ $(COMPOSE) exec $(SERVICE_NAME) npx shadcn@latest add $(component)
+
+i:
+ $(COMPOSE) exec $(SERVICE_NAME) npm install $(package)
\ No newline at end of file
diff --git a/app/(backend)/users/page.tsx b/app/(backend)/users/page.tsx
deleted file mode 100644
index ed4d1fe..0000000
--- a/app/(backend)/users/page.tsx
+++ /dev/null
@@ -1,129 +0,0 @@
-'use client';
-
-import { useState } from "react";
-import { Button } from "@/components/ui/button";
-import { Input } from "@/components/ui/input";
-import { Search, Plus, MoreVertical, Filter } from "lucide-react";
-import { UserMobileCard } from "./components/UserMobileCard";
-import { UserFormWrapper } from "./components/UserFormWrapper";
-
-// Temporary user data for demonstration
-const tempUsers = [
- { id: 1, name: "John Doe", email: "john@example.com", role: "Admin", joinedAt: "2023-01-01", status: "active" },
- { id: 2, name: "Alice Smith", email: "alice@test.com", role: "Editor", joinedAt: "2023-02-15", status: "active" },
- { id: 3, name: "Bob Johnson", email: "bob@community.com", role: "Member", joinedAt: "2023-03-10", status: "inactive" },
- { id: 4, name: "Charlie Brown", email: "charlie@community.com", role: "Member", joinedAt: "2023-04-20", status: "active" },
-];
-
-export default function UsersPage() {
-
- const [open, setOpen] = useState(false)
-
- return (
-
-
-
- {/* Header: Title + Button for Desktop only */}
-
-
-
- Users
-
-
- Manage your community members, roles, and permissions here.
-
-
-
- {/* Button: Add New User for Desktop only */}
-
-
-
- {/* Search + Filter */}
-
-
-
-
-
-
-
-
- {/* Button: Add New User for Mobile only */}
-
-
-
-
-
-
- {/* --- For Mobile Phones --- */}
-
- {tempUsers.map((user) => (
-
- ))}
-
-
- {/* Users List / Table */}
-
-
-
-
- | User |
- Role |
- Status |
- Joined |
- |
-
-
-
- {/* Example Row */}
- {tempUsers.map((user) => (
-
-
-
- {user.name.charAt(0)}
-
- {user.name}
- {user.email}
-
-
- |
-
- {user.role}
- |
-
-
- {user.status}
-
- |
- {user.joinedAt} |
-
-
- |
-
- ))}
-
-
-
-
- );
-}
\ No newline at end of file
diff --git a/app/(backend)/admin/page.tsx b/app/[locale]/(backend)/admin/page.tsx
similarity index 100%
rename from app/(backend)/admin/page.tsx
rename to app/[locale]/(backend)/admin/page.tsx
diff --git a/app/(backend)/layout.tsx b/app/[locale]/(backend)/layout.tsx
similarity index 100%
rename from app/(backend)/layout.tsx
rename to app/[locale]/(backend)/layout.tsx
diff --git a/app/(backend)/page.tsx b/app/[locale]/(backend)/page.tsx
similarity index 97%
rename from app/(backend)/page.tsx
rename to app/[locale]/(backend)/page.tsx
index 5ed737d..1029ffb 100644
--- a/app/(backend)/page.tsx
+++ b/app/[locale]/(backend)/page.tsx
@@ -21,10 +21,12 @@ import {
UserCircle,
Users,
} from "lucide-react";
+import { useTranslations } from "next-intl";
import Link from "next/link";
import React from "react";
const Dashboard: React.FC = () => {
+ const t = useTranslations("dashboard");
const categories: ModuleCategory[] = [
{
title: "People & Community",
@@ -170,11 +172,9 @@ const Dashboard: React.FC = () => {
- Community Dashboard
+ {t("title")}
-
- Welcome to the admin area. Manage your community resources safely.
-
+
{t("welcome")}
diff --git a/app/(backend)/users/components/UserForm/index.tsx b/app/[locale]/(backend)/users/components/UserForm/index.tsx
similarity index 100%
rename from app/(backend)/users/components/UserForm/index.tsx
rename to app/[locale]/(backend)/users/components/UserForm/index.tsx
diff --git a/app/(backend)/users/components/UserFormWrapper.tsx b/app/[locale]/(backend)/users/components/UserFormWrapper.tsx
similarity index 100%
rename from app/(backend)/users/components/UserFormWrapper.tsx
rename to app/[locale]/(backend)/users/components/UserFormWrapper.tsx
diff --git a/app/(backend)/users/components/UserMobileCard/index.tsx b/app/[locale]/(backend)/users/components/UserMobileCard/index.tsx
similarity index 100%
rename from app/(backend)/users/components/UserMobileCard/index.tsx
rename to app/[locale]/(backend)/users/components/UserMobileCard/index.tsx
diff --git a/app/[locale]/(backend)/users/page.tsx b/app/[locale]/(backend)/users/page.tsx
new file mode 100644
index 0000000..97c455e
--- /dev/null
+++ b/app/[locale]/(backend)/users/page.tsx
@@ -0,0 +1,185 @@
+"use client";
+
+import { Button } from "@/components/ui/button";
+import { Input } from "@/components/ui/input";
+import { Filter, MoreVertical, Search } from "lucide-react";
+import { useTranslations } from "next-intl";
+import { useState } from "react";
+import { UserFormWrapper } from "./components/UserFormWrapper";
+import { UserMobileCard } from "./components/UserMobileCard";
+
+// Temporary user data for demonstration
+const tempUsers = [
+ {
+ id: 1,
+ name: "John Doe",
+ email: "john@example.com",
+ role: "Admin",
+ joinedAt: "2023-01-01",
+ status: "active",
+ },
+ {
+ id: 2,
+ name: "Alice Smith",
+ email: "alice@test.com",
+ role: "Editor",
+ joinedAt: "2023-02-15",
+ status: "active",
+ },
+ {
+ id: 3,
+ name: "Bob Johnson",
+ email: "bob@community.com",
+ role: "Member",
+ joinedAt: "2023-03-10",
+ status: "inactive",
+ },
+ {
+ id: 4,
+ name: "Charlie Brown",
+ email: "charlie@community.com",
+ role: "Member",
+ joinedAt: "2023-04-20",
+ status: "active",
+ },
+];
+
+export default function UsersPage() {
+ const [open, setOpen] = useState(false);
+ const t = useTranslations("users");
+
+ return (
+
+
+ {/* Header: Title + Button for Desktop only */}
+
+
+
+ {t("title")}
+
+
+ {t("welcome")}
+
+
+
+ {/* Button: Add New User for Desktop only */}
+
+
+
+ {/* Search + Filter */}
+
+
+
+
+
+
+
+
+ {/* Button: Add New User for Mobile only */}
+
+
+
+
+
+
+ {/* --- For Mobile Phones --- */}
+
+ {tempUsers.map((user) => (
+
+ ))}
+
+
+ {/* Users List / Table */}
+
+
+
+
+ |
+ User
+ |
+
+ Role
+ |
+
+ Status
+ |
+
+ Joined
+ |
+ |
+
+
+
+ {/* Example Row */}
+ {tempUsers.map((user) => (
+
+
+
+
+ {user.name.charAt(0)}
+
+
+
+ {user.name}
+
+
+ {user.email}
+
+
+
+ |
+
+
+ {user.role}
+
+ |
+
+
+ {user.status}
+
+ |
+
+ {user.joinedAt}
+ |
+
+
+ |
+
+ ))}
+
+
+
+
+ );
+}
diff --git a/app/[locale]/layout.tsx b/app/[locale]/layout.tsx
new file mode 100644
index 0000000..0ae30a3
--- /dev/null
+++ b/app/[locale]/layout.tsx
@@ -0,0 +1,45 @@
+import { routing } from "@/i18n/routing";
+import type { Metadata } from "next";
+import { NextIntlClientProvider } from "next-intl";
+import { ThemeProvider } from "next-themes";
+import { Geist, Geist_Mono } from "next/font/google";
+import "../globals.css";
+
+const geistSans = Geist({
+ variable: "--font-geist-sans",
+ subsets: ["latin"],
+});
+
+const geistMono = Geist_Mono({
+ variable: "--font-geist-mono",
+ subsets: ["latin"],
+});
+
+export const metadata: Metadata = {
+ title: "CGR App",
+ description: "Manager for CGR Data",
+};
+
+export default async function RootLayout({
+ children,
+ params,
+}: Readonly<{
+ children: React.ReactNode;
+ params: { locale?: string };
+}>) {
+ const { locale } = await params;
+
+ return (
+
+
+
+
+ {children}
+
+
+
+
+ );
+}
diff --git a/app/layout.tsx b/app/layout.tsx
index 8ed844e..03bcd6e 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -1,35 +1,11 @@
-import type { Metadata } from "next";
-import { ThemeProvider } from "next-themes";
-import { Geist, Geist_Mono } from "next/font/google";
-import "./globals.css";
+import { ReactNode } from "react";
-const geistSans = Geist({
- variable: "--font-geist-sans",
- subsets: ["latin"],
-});
-
-const geistMono = Geist_Mono({
- variable: "--font-geist-mono",
- subsets: ["latin"],
-});
-
-export const metadata: Metadata = {
- title: "CGR App",
- description: "Manager for CGR Data",
+type Props = {
+ children: ReactNode;
};
-export default function RootLayout({
- children,
-}: Readonly<{
- children: React.ReactNode;
-}>) {
- return (
-
-
-
- {children}
-
-
-
- );
+// Since we have a `not-found.tsx` page on the root, a layout file
+// is required, even if it's just passing children through.
+export default function RootLayout({ children }: Props) {
+ return children;
}
diff --git a/components/Header.tsx b/components/Header.tsx
index a348fed..48150af 100644
--- a/components/Header.tsx
+++ b/components/Header.tsx
@@ -1,18 +1,40 @@
+"use client";
+
+import { useTranslations } from "next-intl";
import Image from "next/image";
import Link from "next/link";
import NavItems from "./NavItems";
import UserDropdown from "./UserDropdown";
const Header = () => {
+ const t = useTranslations();
+
return (
-