| @@ -1,4 +1,3 @@ | |||||
| "use client"; | |||||
| import { fetchProjectCategories } from "@/app/api/projects"; | import { fetchProjectCategories } from "@/app/api/projects"; | ||||
| import { preloadStaff } from "@/app/api/staff"; | import { preloadStaff } from "@/app/api/staff"; | ||||
| import { fetchAllTasks, fetchTaskTemplates } from "@/app/api/tasks"; | import { fetchAllTasks, fetchTaskTemplates } from "@/app/api/tasks"; | ||||
| @@ -17,7 +17,7 @@ export default async function RootLayout({ | |||||
| return ( | return ( | ||||
| <html lang={lang}> | <html lang={lang}> | ||||
| <body> | <body> | ||||
| <ThemeRegistry>{children}</ThemeRegistry> | |||||
| <ThemeRegistry lang={lang}>{children}</ThemeRegistry> | |||||
| </body> | </body> | ||||
| </html> | </html> | ||||
| ); | ); | ||||
| @@ -8,6 +8,7 @@ import { | |||||
| ListItemButton, | ListItemButton, | ||||
| ListItemText, | ListItemText, | ||||
| TextField, | TextField, | ||||
| Alert, | |||||
| } from "@mui/material"; | } from "@mui/material"; | ||||
| import { useState, useCallback, useEffect, useMemo } from "react"; | import { useState, useCallback, useEffect, useMemo } from "react"; | ||||
| import { useTranslation } from "react-i18next"; | import { useTranslation } from "react-i18next"; | ||||
| @@ -230,4 +231,28 @@ const ResourceAllocation: React.FC<Props> = ({ | |||||
| ); | ); | ||||
| }; | }; | ||||
| export default ResourceAllocation; | |||||
| const NoTaskState: React.FC = () => { | |||||
| const { t } = useTranslation(); | |||||
| return ( | |||||
| <> | |||||
| <Typography variant="overline" display="block" marginBlockEnd={1}> | |||||
| {t("Task Breakdown")} | |||||
| </Typography> | |||||
| <Alert severity="warning"> | |||||
| {t('Please add some tasks in "Project Task Setup" first!')} | |||||
| </Alert> | |||||
| </> | |||||
| ); | |||||
| }; | |||||
| const ResourceAllocationWrapper: React.FC<Props> = (props) => { | |||||
| const { getValues } = useFormContext<CreateProjectInputs>(); | |||||
| if (Object.keys(getValues("tasks")).length === 0) { | |||||
| return <NoTaskState />; | |||||
| } | |||||
| return <ResourceAllocation {...props} />; | |||||
| }; | |||||
| export default ResourceAllocationWrapper; | |||||
| @@ -12,8 +12,6 @@ import TablePagination, { | |||||
| } from "@mui/material/TablePagination"; | } from "@mui/material/TablePagination"; | ||||
| import TableRow from "@mui/material/TableRow"; | import TableRow from "@mui/material/TableRow"; | ||||
| import IconButton from "@mui/material/IconButton"; | import IconButton from "@mui/material/IconButton"; | ||||
| import { ThemeProvider, createTheme } from "@mui/material"; | |||||
| import { zhTW, enUS } from '@mui/material/locale'; | |||||
| export interface ResultWithId { | export interface ResultWithId { | ||||
| id: string | number; | id: string | number; | ||||
| @@ -67,18 +65,8 @@ function SearchResults<T extends ResultWithId>({ | |||||
| setPage(0); | setPage(0); | ||||
| }; | }; | ||||
| const theme = createTheme( | |||||
| // locale | |||||
| //TODO: May need to know what locale the client is using | |||||
| // localStorage.getItem("locale")?.includes("zh") ? zhTW : enUS | |||||
| zhTW | |||||
| ); | |||||
| const table = ( | const table = ( | ||||
| <> | <> | ||||
| <ThemeProvider theme={theme}> | |||||
| <TableContainer sx={{ maxHeight: 440 }}> | <TableContainer sx={{ maxHeight: 440 }}> | ||||
| <Table stickyHeader> | <Table stickyHeader> | ||||
| <TableHead> | <TableHead> | ||||
| @@ -129,7 +117,6 @@ function SearchResults<T extends ResultWithId>({ | |||||
| onPageChange={handleChangePage} | onPageChange={handleChangePage} | ||||
| onRowsPerPageChange={handleChangeRowsPerPage} | onRowsPerPageChange={handleChangeRowsPerPage} | ||||
| /> | /> | ||||
| </ThemeProvider> | |||||
| </> | </> | ||||
| ); | ); | ||||
| @@ -1,19 +1,36 @@ | |||||
| "use client"; | "use client"; | ||||
| import * as React from "react"; | import * as React from "react"; | ||||
| import { ThemeProvider } from "@mui/material/styles"; | |||||
| import { ThemeProvider, createTheme } from "@mui/material/styles"; | |||||
| import CssBaseline from "@mui/material/CssBaseline"; | import CssBaseline from "@mui/material/CssBaseline"; | ||||
| import NextAppDirEmotionCacheProvider from "./EmotionCache"; | import NextAppDirEmotionCacheProvider from "./EmotionCache"; | ||||
| import theme from "./devias-material-kit"; | import theme from "./devias-material-kit"; | ||||
| import { zhHK, enUS } from "@mui/material/locale"; | |||||
| const getLocalizationFromLang = (lang: string) => { | |||||
| switch (lang) { | |||||
| case "zh": | |||||
| return zhHK; | |||||
| default: | |||||
| return enUS; | |||||
| } | |||||
| }; | |||||
| // Copied from https://github.com/mui/material-ui/blob/master/examples/material-ui-nextjs-ts/src/components/ThemeRegistry/ThemeRegistry.tsx | // Copied from https://github.com/mui/material-ui/blob/master/examples/material-ui-nextjs-ts/src/components/ThemeRegistry/ThemeRegistry.tsx | ||||
| export default function ThemeRegistry({ | export default function ThemeRegistry({ | ||||
| children, | children, | ||||
| lang, | |||||
| }: { | }: { | ||||
| children: React.ReactNode; | children: React.ReactNode; | ||||
| lang: string; | |||||
| }) { | }) { | ||||
| const themeWithLocale = React.useMemo( | |||||
| () => createTheme(theme, getLocalizationFromLang(lang)), | |||||
| [lang], | |||||
| ); | |||||
| return ( | return ( | ||||
| <NextAppDirEmotionCacheProvider options={{ key: "mui" }}> | <NextAppDirEmotionCacheProvider options={{ key: "mui" }}> | ||||
| <ThemeProvider theme={theme}> | |||||
| <ThemeProvider theme={themeWithLocale}> | |||||
| <CssBaseline /> | <CssBaseline /> | ||||
| {children} | {children} | ||||
| </ThemeProvider> | </ThemeProvider> | ||||