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 ( + <> + + + + + ); +}; + +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)))} )}