diff --git a/src/app/(main)/settings/import/page.tsx b/src/app/(main)/settings/import/page.tsx
new file mode 100644
index 0000000..46fde8a
--- /dev/null
+++ b/src/app/(main)/settings/import/page.tsx
@@ -0,0 +1,34 @@
+import { Metadata } from "next";
+import { getServerI18n } from "@/i18n";
+import Stack from "@mui/material/Stack";
+import Typography from "@mui/material/Typography";
+import { Suspense } from "react";
+import ExcelFileImport from "@/components/ExcelFileImport";
+
+export const metadata: Metadata = {
+ title: "Excel File Import",
+};
+
+const Import: React.FC = async () => {
+ const { t } = await getServerI18n("holiday");
+
+ return (
+ <>
+
+
+ {t("Excel File Import")}
+
+
+
+
+
+ >
+ )
+};
+
+export default Import;
diff --git a/src/app/api/projects/actions.ts b/src/app/api/projects/actions.ts
index 31ab2c9..d1d3e47 100644
--- a/src/app/api/projects/actions.ts
+++ b/src/app/api/projects/actions.ts
@@ -2,6 +2,7 @@
import {
serverFetchJson,
+ serverFetchString,
serverFetchWithNoContent,
} from "@/app/utils/fetchUtil";
import { BASE_API_URL } from "@/config/api";
@@ -83,6 +84,7 @@ export interface CreateProjectResponse {
team: string;
client: string;
}
+
export const saveProject = async (data: CreateProjectInputs) => {
const newProject = await serverFetchJson(
`${BASE_API_URL}/projects/new`,
@@ -110,3 +112,15 @@ export const deleteProject = async (id: number) => {
revalidatePath("/(main)/home");
return project;
};
+
+export const importProjects = async (data: FormData) => {
+ const importProjects = await serverFetchString(
+ `${BASE_API_URL}/projects/import`,
+ {
+ method: "POST",
+ body: data,
+ },
+ );
+
+ return importProjects;
+};
diff --git a/src/components/AppBar/AppBar.tsx b/src/components/AppBar/AppBar.tsx
index 10cf3fe..f5a2093 100644
--- a/src/components/AppBar/AppBar.tsx
+++ b/src/components/AppBar/AppBar.tsx
@@ -16,12 +16,13 @@ export interface AppBarProps {
const AppBar: React.FC = async ({ avatarImageSrc, profileName }) => {
const session = await getServerSession(authOptions) as any;
const abilities: string[] = session.abilities
+ const username: string = session.user.name
// console.log(abilities)
return (
-
+
diff --git a/src/components/AppBar/NavigationToggle.tsx b/src/components/AppBar/NavigationToggle.tsx
index f704267..ca91eb7 100644
--- a/src/components/AppBar/NavigationToggle.tsx
+++ b/src/components/AppBar/NavigationToggle.tsx
@@ -8,14 +8,16 @@ import { Session } from "inspector";
import { authOptions } from "@/config/authConfig";
import { getServerSession } from "next-auth";
export interface SessionWithAbilities extends Session {
- abilities?: string[]
+ abilities?: string[],
+ username?: string
}
interface Props {
- abilities?: string[]
+ abilities?: string[],
+ username?: string
}
-const NavigationToggle: React.FC = ({ abilities }) => {
+const NavigationToggle: React.FC = ({ abilities, username }) => {
const [isOpened, setIsOpened] = React.useState(false);
const openNavigation = () => {
@@ -28,7 +30,7 @@ const NavigationToggle: React.FC = ({ abilities }) => {
return (
<>
-
+
= async ({ }) => {
+
+ const { t } = useTranslation("projects");
+
+ const handleProjectImportClick = useCallback(async (event: ChangeEvent) => {
+
+ try {
+ console.log(event.target.files)
+ if (event.target.files !== null) {
+ const file = event.target.files[0]
+ const formData = new FormData();
+ formData.append('multipartFileList', file);
+
+ if (file.name.endsWith(".xlsx") || file.name.endsWith(".csv")) {
+ const response = await importProjects(formData)
+
+ if (response === "Import Excel success") {
+ successDialog(t("Import Success"), t)
+ } else {
+ errorDialogWithContent(t("Import Fail"), t(`${response}`), t)
+ }
+ }
+ }
+
+ } catch (err) {
+ console.log(err)
+ return false
+ }
+
+ return
+ }, [])
+
+ return (
+ <>
+
+ }
+ component="label"
+ >
+ {
+ handleProjectImportClick(event)
+ }}
+ />
+ {t("Import Project")}
+
+
+ >
+ );
+};
+
+export default ExcelFileImport;
\ No newline at end of file
diff --git a/src/components/ExcelFileImport/ExcelFileImportWrapper.tsx b/src/components/ExcelFileImport/ExcelFileImportWrapper.tsx
new file mode 100644
index 0000000..ad0723a
--- /dev/null
+++ b/src/components/ExcelFileImport/ExcelFileImportWrapper.tsx
@@ -0,0 +1,12 @@
+import React from "react";
+import { fetchProjects } from "@/app/api/projects";
+import ExcelFileImport from "./ExcelFileImport";
+import { getUserStaff } from "@/app/utils/commonUtil";
+
+const ExcelFileImportWrapper: React.FC = async () => {
+
+ return ;
+};
+
+
+export default ExcelFileImportWrapper;
\ No newline at end of file
diff --git a/src/components/ExcelFileImport/index.ts b/src/components/ExcelFileImport/index.ts
new file mode 100644
index 0000000..542fe57
--- /dev/null
+++ b/src/components/ExcelFileImport/index.ts
@@ -0,0 +1 @@
+export { default } from './ExcelFileImportWrapper'
\ No newline at end of file
diff --git a/src/components/NavigationContent/NavigationContent.tsx b/src/components/NavigationContent/NavigationContent.tsx
index 9b36523..1332fe6 100644
--- a/src/components/NavigationContent/NavigationContent.tsx
+++ b/src/components/NavigationContent/NavigationContent.tsx
@@ -34,6 +34,7 @@ import BusinessIcon from "@mui/icons-material/Business";
import ViewWeekIcon from "@mui/icons-material/ViewWeek";
import ManageAccountsIcon from "@mui/icons-material/ManageAccounts";
import EmojiEventsIcon from "@mui/icons-material/EmojiEvents";
+import FileUploadIcon from '@mui/icons-material/FileUpload';
import {
GENERATE_REPORTS,
IMPORT_INVOICE,
@@ -63,9 +64,10 @@ interface NavigationItem {
interface Props {
abilities?: string[];
+ username?: string;
}
-const NavigationContent: React.FC = ({ abilities }) => {
+const NavigationContent: React.FC = ({ abilities, username }) => {
const navigationItems: NavigationItem[] = [
{
icon: ,
@@ -242,7 +244,8 @@ const NavigationContent: React.FC = ({ abilities }) => {
label: "User Group",
path: "/settings/group",
},
- { icon: , label: "Holiday", path: "/settings/holiday" },
+ { icon: , label: "Holiday", path: "/settings/holiday"},
+ { icon: , label: "Import Excel File", path: "/settings/import", isHidden: username !== "2fi"},
],
},
];
@@ -279,7 +282,7 @@ const NavigationContent: React.FC = ({ abilities }) => {
{item.children && isOpen && (
- {item.children.map((child) => renderNavigationItem(child))}
+ {item.children.map((child) => (!child.isHidden && renderNavigationItem(child)))}
)}