diff --git a/src/app/(main)/settings/company/create/page.tsx b/src/app/(main)/settings/company/create/page.tsx
new file mode 100644
index 0000000..1702f2d
--- /dev/null
+++ b/src/app/(main)/settings/company/create/page.tsx
@@ -0,0 +1,22 @@
+import { fetchProjectCategories } from "@/app/api/projects";
+import { preloadStaff } from "@/app/api/staff";
+import { fetchAllTasks, fetchTaskTemplates } from "@/app/api/tasks";
+import CreateProject from "@/components/CreateProject";
+import { I18nProvider, getServerI18n } from "@/i18n";
+import Typography from "@mui/material/Typography";
+import { Metadata } from "next";
+
+export const metadata: Metadata = {
+ title: "Create Project",
+ };
+
+const Companys: React.FC = async () => {
+ const { t } = await getServerI18n("projects");
+
+ return(
+ <>AAAA>
+ )
+
+}
+
+export default Companys;
\ No newline at end of file
diff --git a/src/app/(main)/settings/company/page.tsx b/src/app/(main)/settings/company/page.tsx
new file mode 100644
index 0000000..26332c1
--- /dev/null
+++ b/src/app/(main)/settings/company/page.tsx
@@ -0,0 +1,50 @@
+import CompanySearch from "@/components/CompanySearch";
+import { Metadata } from "next";
+import { getServerI18n } from "@/i18n";
+import Add from "@mui/icons-material/Add";
+import Button from "@mui/material/Button";
+import Stack from "@mui/material/Stack";
+import Typography from "@mui/material/Typography";
+import Link from "next/link";
+import { Suspense } from "react";
+import { fetchCompanys, preloadCompanys } from "@/app/api/companys";
+
+export const metadata: Metadata = {
+ title: "Company",
+};
+
+const Company: React.FC = async () => {
+ const { t } = await getServerI18n("companys");
+
+ // Preload necessary dependencies
+ fetchCompanys();
+ preloadCompanys();
+
+ return (
+ <>
+
+
+ {t("Company")}
+
+ }
+ LinkComponent={Link}
+ href="/settings/company/create"
+ >
+ {t("Create Company")}
+
+
+ }>
+
+
+ >
+ )
+};
+
+export default Company;
diff --git a/src/app/api/companys/index.ts b/src/app/api/companys/index.ts
new file mode 100644
index 0000000..3211d1c
--- /dev/null
+++ b/src/app/api/companys/index.ts
@@ -0,0 +1,24 @@
+import { serverFetchJson } from "@/app/utils/fetchUtil";
+import { BASE_API_URL } from "@/config/api";
+import { cache } from "react";
+import "server-only";
+
+export interface CompanyResult {
+ id: number;
+ companyCode: string;
+ name: string;
+ brNo: string;
+ contactName: string;
+ phone: string
+ email: string;
+}
+
+export const preloadCompanys = () => {
+ fetchCompanys();
+};
+
+export const fetchCompanys = cache(async () => {
+ return serverFetchJson(`${BASE_API_URL}/companys`, {
+ next: { tags: ["companys"] },
+ });
+});
\ No newline at end of file
diff --git a/src/components/Breadcrumb/Breadcrumb.tsx b/src/components/Breadcrumb/Breadcrumb.tsx
index fbb68e2..44b16a8 100644
--- a/src/components/Breadcrumb/Breadcrumb.tsx
+++ b/src/components/Breadcrumb/Breadcrumb.tsx
@@ -15,6 +15,7 @@ const pathToLabelMap: { [path: string]: string } = {
"/tasks/create": "Create Task Template",
"/customer": "Customer",
"/customer/create": "Create Customer",
+ "/company": "Company",
};
const Breadcrumb = () => {
diff --git a/src/components/CompanySearch/CompanySearch.tsx b/src/components/CompanySearch/CompanySearch.tsx
new file mode 100644
index 0000000..27a9635
--- /dev/null
+++ b/src/components/CompanySearch/CompanySearch.tsx
@@ -0,0 +1,87 @@
+"use client";
+
+import { CompanyResult } from "@/app/api/companys";
+import React, { useCallback, useMemo, useState } from "react";
+import SearchBox, { Criterion } from "../SearchBox";
+import { useTranslation } from "react-i18next";
+import SearchResults, { Column } from "../SearchResults";
+import EditNote from "@mui/icons-material/EditNote";
+import uniq from "lodash/uniq";
+
+interface Props {
+ companys: CompanyResult[];
+}
+
+type SearchQuery = Partial>;
+type SearchParamNames = keyof SearchQuery;
+
+const CompanySearch: React.FC = ({ companys }) => {
+ const { t } = useTranslation("companys");
+
+ const [filteredCompanys, setFilteredCompanys] = useState(companys);
+
+ const searchCriteria: Criterion[] = useMemo(
+ () => [
+ { label: t("Company code"), paramName: "companyCode", type: "text" },
+ { label: t("Company name"), paramName: "name", type: "text" },
+ { label: t("Contact Name"), paramName: "contactName", type: "text" },
+ { label: t("Contact Number"), paramName: "phone", type: "text" },
+ ],
+ [t, companys],
+ );
+
+ const onReset = useCallback(() => {
+ setFilteredCompanys(companys);
+ }, [companys]);
+
+ const onProjectClick = useCallback((project: CompanyResult) => {
+ console.log(project);
+ }, []);
+
+ const columns = useMemo[]>(
+ () => [
+ {
+ name: "id",
+ label: t("Details"),
+ onClick: onProjectClick,
+ buttonIcon: ,
+ },
+ { name: "companyCode", label: t("Company Code") },
+ { name: "name", label: t("Company Name") },
+ { name: "brNo", label: t("brNo") },
+ { name: "contactName", label: t("Contact Name") },
+ { name: "phone", label: t("Contact No.") },
+ { name: "email", label: t("Contact Email") }
+ ],
+ [t, onProjectClick],
+ );
+
+ return (
+ <>
+ {
+ setFilteredCompanys(
+ companys.filter(
+ (p) =>
+ p.companyCode.toLowerCase().includes(query.companyCode.toLowerCase()) &&
+ p.name.toLowerCase().includes(query.name.toLowerCase()) &&
+ p.contactName.toLowerCase().includes(query.contactName.toLowerCase()) &&
+ p.phone.toLowerCase().includes(query.phone.toLowerCase()) &&
+ {/*(query.client === "All" || p.client === query.client) &&
+ (query.category === "All" || p.category === query.category) &&
+ (query.team === "All" || p.team === query.team), **/}
+ ),
+ );
+ }}
+ onReset={onReset}
+ />
+
+ items={filteredCompanys}
+ columns={columns}
+ />
+ >
+ );
+};
+
+export default CompanySearch;
diff --git a/src/components/CompanySearch/CompanySearchLoading.tsx b/src/components/CompanySearch/CompanySearchLoading.tsx
new file mode 100644
index 0000000..68eb7a6
--- /dev/null
+++ b/src/components/CompanySearch/CompanySearchLoading.tsx
@@ -0,0 +1,40 @@
+import Card from "@mui/material/Card";
+import CardContent from "@mui/material/CardContent";
+import Skeleton from "@mui/material/Skeleton";
+import Stack from "@mui/material/Stack";
+import React from "react";
+
+// Can make this nicer
+export const CompanySearchLoading: React.FC = () => {
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+};
+
+export default CompanySearchLoading;
diff --git a/src/components/CompanySearch/CompanySearchWrapper.tsx b/src/components/CompanySearch/CompanySearchWrapper.tsx
new file mode 100644
index 0000000..f7e61a0
--- /dev/null
+++ b/src/components/CompanySearch/CompanySearchWrapper.tsx
@@ -0,0 +1,20 @@
+// import { fetchCompanyCategories, fetchCompanys } from "@/app/api/companys";
+import React from "react";
+import CompanySearch from "./CompanySearch";
+import CompanySearchLoading from "./CompanySearchLoading";
+import { fetchCompanys } from "@/app/api/companys";
+
+interface SubComponents {
+ Loading: typeof CompanySearchLoading;
+}
+
+const CompanySearchWrapper: React.FC & SubComponents = async () => {
+ // const Companys = await fetchCompanys();
+ const Companys = await fetchCompanys();
+
+ return ;
+};
+
+CompanySearchWrapper.Loading = CompanySearchLoading;
+
+export default CompanySearchWrapper;
diff --git a/src/components/CompanySearch/index.ts b/src/components/CompanySearch/index.ts
new file mode 100644
index 0000000..69bd2a2
--- /dev/null
+++ b/src/components/CompanySearch/index.ts
@@ -0,0 +1 @@
+export { default } from "./CompanySearchWrapper";
diff --git a/src/components/NavigationContent/NavigationContent.tsx b/src/components/NavigationContent/NavigationContent.tsx
index 1bb497e..9eb5ebc 100644
--- a/src/components/NavigationContent/NavigationContent.tsx
+++ b/src/components/NavigationContent/NavigationContent.tsx
@@ -91,7 +91,8 @@ const navigationItems: NavigationItem[] = [
icon: , label: "Setting", path: "",
children: [
{ icon: , label: "Customer", path: "/customer" },
- { icon: , label: "Staff", path: "/staff" }
+ { icon: , label: "Staff", path: "/staff" },
+ { icon: , label: "Company", path: "/settings/company" }
],
},
];