Pārlūkot izejas kodu

Update user workspace design

tags/Baseline_30082024_FRONTEND_UAT
Wayne pirms 1 gada
vecāks
revīzija
0d0ed01709
13 mainītis faili ar 359 papildinājumiem un 431 dzēšanām
  1. +13
    -0
      package-lock.json
  2. +1
    -0
      package.json
  3. +1
    -1
      src/app/(main)/home/page.tsx
  4. +0
    -247
      src/components/AssignedProjectGrid/AssignedProjectGrid.tsx
  5. +0
    -1
      src/components/AssignedProjectGrid/index.ts
  6. +2
    -1
      src/components/Breadcrumb/Breadcrumb.tsx
  7. +1
    -17
      src/components/EnterLeave/EnterLeaveModal.tsx
  8. +1
    -17
      src/components/EnterTimesheet/EnterTimesheetModal.tsx
  9. +117
    -0
      src/components/UserWorkspacePage/AssignedProjects.tsx
  10. +104
    -92
      src/components/UserWorkspacePage/ProjectGrid.tsx
  11. +53
    -54
      src/components/UserWorkspacePage/UserWorkspacePage.tsx
  12. +65
    -0
      src/components/UserWorkspacePage/UserWorkspaceWrapper.tsx
  13. +1
    -1
      src/components/UserWorkspacePage/index.ts

+ 13
- 0
package-lock.json Parādīt failu

@@ -33,6 +33,7 @@
"react-hook-form": "^7.49.2",
"react-i18next": "^13.5.0",
"react-intl": "^6.5.5",
"react-number-format": "^5.3.4",
"react-select": "^5.8.0",
"reactstrap": "^9.2.2",
"styled-components": "^6.1.8",
@@ -8031,6 +8032,18 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/react-number-format": {
"version": "5.3.4",
"resolved": "https://registry.npmjs.org/react-number-format/-/react-number-format-5.3.4.tgz",
"integrity": "sha512-2hHN5mbLuCDUx19bv0Q8wet67QqYK6xmtLQeY5xx+h7UXiMmRtaCwqko4mMPoKXLc6xAzwRrutg8XbTRlsfjRg==",
"dependencies": {
"prop-types": "^15.7.2"
},
"peerDependencies": {
"react": "^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/react-popper": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.3.0.tgz",


+ 1
- 0
package.json Parādīt failu

@@ -34,6 +34,7 @@
"react-hook-form": "^7.49.2",
"react-i18next": "^13.5.0",
"react-intl": "^6.5.5",
"react-number-format": "^5.3.4",
"react-select": "^5.8.0",
"reactstrap": "^9.2.2",
"styled-components": "^6.1.8",


+ 1
- 1
src/app/(main)/home/page.tsx Parādīt failu

@@ -1,6 +1,6 @@
import { Metadata } from "next";
import { I18nProvider } from "@/i18n";
import UserWorkspacePage from "@/components/UserWorkspacePage/UserWorkspacePage";
import UserWorkspacePage from "@/components/UserWorkspacePage";

export const metadata: Metadata = {
title: "User Workspace",


+ 0
- 247
src/components/AssignedProjectGrid/AssignedProjectGrid.tsx Parādīt failu

@@ -1,247 +0,0 @@
import * as React from "react";
import {
Card,
CardHeader,
CardContent,
SxProps,
Theme,
Tabs,
Tab,
Box,
Typography,
Grid,
Link,
} from "@mui/material";
import { DataGrid, GridColDef } from "@mui/x-data-grid";
import { darken, lighten, styled } from "@mui/material/styles";
import { ThemeProvider } from "@emotion/react";
import { TAB_THEME } from "@/theme/colorConst";
import AllProjectGrid from "../UserWorkspacePage/ProjectGrid";

interface AssignedProjectGridProps {
Title?: string;
// rows: any[];
// columns: any[];
columnWidth?: number;
Style?: boolean;
sx?: SxProps<Theme>;
height?: number;
[key: string]: any;
}

interface TabPanelProps {
children?: React.ReactNode;
index: number;
value: number;
}

function CustomTabPanel(props: TabPanelProps) {
const { children, value, index, ...other } = props;

return (
<div
role="tabpanel"
hidden={value !== index}
id={`simple-tabpanel-${index}`}
aria-labelledby={`simple-tab-${index}`}
{...other}
>
{value === index && (
<Box sx={{ p: 3 }}>
<Typography>{children}</Typography>
</Box>
)}
</div>
);
}

function a11yProps(index: number) {
return {
id: `simple-tab-${index}`,
"aria-controls": `simple-tabpanel-${index}`,
};
}

const AssignedProjectGrid: React.FC<AssignedProjectGridProps> = ({
Title,
rows,
columns,
columnWidth,
Style = true,
sx,
height,
...props
}) => {
// const modifiedColumns = columns.map((column) => {
// return {
// ...column,
// width: columnWidth ?? 150,
// };
// });

// const rowsWithDefaultValues = rows.map((row) => {
// return { ...row };
// });

const getBackgroundColor = (color: string, mode: "light" | "dark") =>
mode === "dark" ? darken(color, 0.7) : lighten(color, 0.7);

const getHoverBackgroundColor = (color: string, mode: "light" | "dark") =>
mode === "dark" ? darken(color, 0.6) : lighten(color, 0.6);

const getSelectedBackgroundColor = (color: string, mode: "light" | "dark") =>
mode === "dark" ? darken(color, 0.5) : lighten(color, 0.5);

const getSelectedHoverBackgroundColor = (
color: string,
mode: "light" | "dark",
) => (mode === "dark" ? darken(color, 0.4) : lighten(color, 0.4));

const StyledDataGrid = styled(DataGrid)(({ theme }) => ({
"& .super-app-theme--Open": {
backgroundColor: getBackgroundColor(
theme.palette.info.main,
theme.palette.mode,
),
"&:hover": {
backgroundColor: getHoverBackgroundColor(
theme.palette.info.main,
theme.palette.mode,
),
},
"&.Mui-selected": {
backgroundColor: getSelectedBackgroundColor(
theme.palette.info.main,
theme.palette.mode,
),
"&:hover": {
backgroundColor: getSelectedHoverBackgroundColor(
theme.palette.info.main,
theme.palette.mode,
),
},
},
},
"& .super-app-theme--finish": {
backgroundColor: getBackgroundColor(
theme.palette.success.main,
theme.palette.mode,
),
"&:hover": {
backgroundColor: getHoverBackgroundColor(
theme.palette.success.main,
theme.palette.mode,
),
},
"&.Mui-selected": {
backgroundColor: getSelectedBackgroundColor(
theme.palette.success.main,
theme.palette.mode,
),
"&:hover": {
backgroundColor: getSelectedHoverBackgroundColor(
theme.palette.success.main,
theme.palette.mode,
),
},
},
},
"& .super-app-theme--danger": {
backgroundColor: getBackgroundColor(
theme.palette.warning.main,
theme.palette.mode,
),
"&:hover": {
backgroundColor: getHoverBackgroundColor(
theme.palette.warning.main,
theme.palette.mode,
),
},
"&.Mui-selected": {
backgroundColor: getSelectedBackgroundColor(
theme.palette.warning.main,
theme.palette.mode,
),
"&:hover": {
backgroundColor: getSelectedHoverBackgroundColor(
theme.palette.warning.main,
theme.palette.mode,
),
},
},
},
"& .super-app-theme--warning": {
backgroundColor: getBackgroundColor(
theme.palette.error.main,
theme.palette.mode,
),
"&:hover": {
backgroundColor: getHoverBackgroundColor(
theme.palette.error.main,
theme.palette.mode,
),
},
"&.Mui-selected": {
backgroundColor: getSelectedBackgroundColor(
theme.palette.error.main,
theme.palette.mode,
),
"&:hover": {
backgroundColor: getSelectedHoverBackgroundColor(
theme.palette.error.main,
theme.palette.mode,
),
},
},
},
}));

const [value, setValue] = React.useState(0);

const handleChange = (event: React.SyntheticEvent, newValue: number) => {
setValue(newValue);
};

return (
<div style={{ height: height ?? 400, width: "100%" }}>
<Card style={{ margin: "auto 20px auto 20px" }}>
{Title && <CardHeader title={Title} />}
<CardContent
style={{
padding: "0px 24px 24px 24px",
display: "flex",
alignItems: "center",
}}
>
<div>
<ThemeProvider theme={TAB_THEME}>
<Box sx={{ borderBottom: 4, borderColor: "divider" }}>
<Tabs
value={value}
onChange={handleChange}
aria-label="Manage assigned project"
>
<Tab label="All Projects" {...a11yProps(0)} />
<Tab label="On Track" {...a11yProps(1)} />
<Tab label="Potential Delay" {...a11yProps(2)} />
</Tabs>
</Box>
{/* <CustomTabPanel value={value} index={0}>
Item {value}
</CustomTabPanel>
<CustomTabPanel value={value} index={1}>
Item {value}
</CustomTabPanel>
<CustomTabPanel value={value} index={2}>
Item {value}
</CustomTabPanel> */}
</ThemeProvider>
</div>
</CardContent>
<AllProjectGrid tab={value} />
</Card>
</div>
);
};

export default AssignedProjectGrid;

+ 0
- 1
src/components/AssignedProjectGrid/index.ts Parādīt failu

@@ -1 +0,0 @@
export { default } from "./AssignedProjectGrid";

+ 2
- 1
src/components/Breadcrumb/Breadcrumb.tsx Parādīt failu

@@ -9,6 +9,7 @@ import { useTranslation } from "react-i18next";

const pathToLabelMap: { [path: string]: string } = {
"": "Overview",
"/home": "User Workspace",
"/projects": "Projects",
"/projects/create": "Create Project",
"/tasks": "Task Template",
@@ -26,7 +27,7 @@ const pathToLabelMap: { [path: string]: string } = {
const Breadcrumb = () => {
const pathname = usePathname();
const segments = pathname.split("/");
// const { t } = useTranslation("customer");

return (


+ 1
- 17
src/components/EnterLeave/EnterLeaveModal.tsx Parādīt failu

@@ -1,25 +1,9 @@
"use client";

// import { testing } from "@/app/api/timesheets";
import Grid from "@mui/material/Grid";
import Paper from "@mui/material/Paper";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import AssignedProjectGrid from "../AssignedProjectGrid/AssignedProjectGrid";
import PageTitle from "../PageTitle/PageTitle";
import { Suspense } from "react";
import Button from "@mui/material/Button";
import Stack from "@mui/material/Stack";
import { Add } from "@mui/icons-material";
import Link from "next/link";
import { t } from "i18next";
import { Card, Modal, Typography } from "@mui/material";
import CustomModal from "../CustomModal/CustomModal";
import { PROJECT_MODAL_STYLE } from "@/theme/colorConst";
import CustomDatagrid from "../CustomDatagrid/CustomDatagrid";
import { DataGrid } from "@mui/x-data-grid";
import { Card, Modal } from "@mui/material";
import TimesheetInputGrid from "./LeaveInputGrid";
import { BASE_API_URL } from "@/config/api";

// import { fetchLeaves } from "@/app/api/leave";



+ 1
- 17
src/components/EnterTimesheet/EnterTimesheetModal.tsx Parādīt failu

@@ -1,25 +1,9 @@
"use client";

// import { testing } from "@/app/api/timesheets";
import Grid from "@mui/material/Grid";
import Paper from "@mui/material/Paper";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import AssignedProjectGrid from "../AssignedProjectGrid/AssignedProjectGrid";
import PageTitle from "../PageTitle/PageTitle";
import { Suspense } from "react";
import Button from "@mui/material/Button";
import Stack from "@mui/material/Stack";
import { Add } from "@mui/icons-material";
import Link from "next/link";
import { t } from "i18next";
import { Card, Modal, Typography } from "@mui/material";
import CustomModal from "../CustomModal/CustomModal";
import { PROJECT_MODAL_STYLE } from "@/theme/colorConst";
import CustomDatagrid from "../CustomDatagrid/CustomDatagrid";
import { DataGrid } from "@mui/x-data-grid";
import { Card, Modal } from "@mui/material";
import TimesheetInputGrid from "./TimesheetInputGrid";
import { BASE_API_URL } from "@/config/api";

// import { fetchTimesheets } from "@/app/api/timesheets";



+ 117
- 0
src/components/UserWorkspacePage/AssignedProjects.tsx Parādīt failu

@@ -0,0 +1,117 @@
import React, { useEffect, useMemo } from "react";
import {
Card,
CardContent,
FormControl,
Grid,
IconButton,
InputAdornment,
InputLabel,
MenuItem,
Select,
SelectChangeEvent,
Stack,
TextField,
Typography,
} from "@mui/material";
import { useTranslation } from "react-i18next";
import { Clear, Search } from "@mui/icons-material";
import ProjectGrid from "./ProjectGrid";
import { Props as UserWorkspaceProps } from "./UserWorkspacePage";
import uniq from "lodash/uniq";

const AssignedProjects: React.FC<UserWorkspaceProps> = ({ allProjects }) => {
const { t } = useTranslation("home");

// Projects
const [filteredProjects, setFilterProjects] = React.useState(allProjects);

// Query related
const [query, setQuery] = React.useState("");
const onQueryInputChange = React.useCallback<
React.ChangeEventHandler<HTMLInputElement>
>((e) => {
setQuery(e.target.value);
}, []);
const clearQueryInput = React.useCallback(() => {
setQuery("");
}, []);

// Filter
const allStatuses = useMemo(() => {
return uniq([
"All",
...allProjects.map((project) => project.projectStatus),
]);
}, [allProjects]);
const [statusFilter, setStatusFilter] = React.useState("All");
const onStatusChange = React.useCallback((e: SelectChangeEvent) => {
setStatusFilter(e.target.value);
}, []);

useEffect(() => {
setFilterProjects(
allProjects.filter(
(p) =>
(p.code.toLowerCase().includes(query.toLowerCase()) ||
p.name.toLowerCase().includes(query.toLowerCase())) &&
(p.projectStatus === statusFilter || statusFilter === "All"),
),
);
}, [allProjects, query, statusFilter]);

return (
<>
<Card>
<CardContent>
<Stack gap={2}>
<Typography variant="overline" display="block">
{t("Assigned Projects")}
</Typography>
<Grid container spacing={2} columns={{ xs: 6, sm: 12 }}>
<Grid item xs={6} display="flex" alignItems="center">
<Search sx={{ marginInlineEnd: 1 }} />
<TextField
variant="standard"
fullWidth
onChange={onQueryInputChange}
value={query}
placeholder={t("Search projects by name or code")}
InputProps={{
endAdornment: query && (
<InputAdornment position="end">
<IconButton onClick={clearQueryInput}>
<Clear />
</IconButton>
</InputAdornment>
),
}}
/>
</Grid>
<Grid item xs={3}>
<FormControl fullWidth>
<InputLabel size="small">{t("Project Status")}</InputLabel>
<Select
label={t("Project Status")}
size="small"
value={statusFilter}
onChange={onStatusChange}
>
{allStatuses.map((option, index) => (
<MenuItem key={`${option}-${index}`} value={option}>
{option}
</MenuItem>
))}
</Select>
</FormControl>
</Grid>
</Grid>
</Stack>
</CardContent>
</Card>
<ProjectGrid projects={filteredProjects} />
</>
);
};

export default AssignedProjects;

+ 104
- 92
src/components/UserWorkspacePage/ProjectGrid.tsx Parādīt failu

@@ -1,99 +1,111 @@
"use client";
import * as React from "react";
import Grid from "@mui/material/Grid";
import { useEffect } from "react";
import { Card, CardContent, CardHeader } from "@mui/material";
import CustomCardGrid from "../CustomCardGrid/CustomCardGrid";
import "../../app/global.css";
import { PROJECT_CARD_STYLE } from "@/theme/colorConst";
import React from "react";
import { ProjectHours } from "./UserWorkspaceWrapper";
import { Box, Card, CardContent, Chip, Grid, Typography } from "@mui/material";
import { useTranslation } from "react-i18next";
import { manhourFormatter } from "@/app/utils/formatUtil";

interface ProjectGridProps {
tab: number;
interface Props {
projects: ProjectHours[];
}

const cards = [
{
code: "M1001 (C)",
name: "Consultancy Project A",
hr_spent: 12.75,
hr_spent_normal: 0.0,
hr_alloc: 150.0,
hr_alloc_normal: 30.0,
},
{
code: "M1301 (C)",
name: "Consultancy Project AAA",
hr_spent: 4.25,
hr_spent_normal: 0.25,
hr_alloc: 30.0,
hr_alloc_normal: 0.0,
},
{
code: "M1354 (C)",
name: "Consultancy Project BBB",
hr_spent: 57.0,
hr_spent_normal: 6.5,
hr_alloc: 100.0,
hr_alloc_normal: 20.0,
},
{
code: "M1973 (C)",
name: "Construction Project CCC",
hr_spent: 12.75,
hr_spent_normal: 0.0,
hr_alloc: 150.0,
hr_alloc_normal: 30.0,
},
{
code: "M2014 (T)",
name: "Consultancy Project DDD",
hr_spent: 1.0,
hr_spent_normal: 0.0,
hr_alloc: 10.0,
hr_alloc_normal: 0.0,
},
];

const ProjectGrid: React.FC<ProjectGridProps> = (props) => {
const [items, setItems] = React.useState<typeof cards>([]);

useEffect(() => {
if (props.tab == 0) {
setItems(cards);
} else {
const filteredItems = cards; //cards.filter(item => (item.track == props.tab));
setItems(filteredItems);
}
}, [props.tab]);

const cardLayout = (item: Record<string, string>) => {
return (
<Card style={PROJECT_CARD_STYLE}>
<CardHeader
style={{ backgroundColor: "pink" }}
title={item.code + "\u000A" + item.name}
/>
<CardContent>
<p>Hours Spent: {item.hr_spent}</p>
<p>Normal (Others): {item.hr_spent_normal}</p>
<p>Hours Allocated: {item.hr_alloc}</p>
<p>Normal (Others): {item.hr_alloc_normal}</p>
</CardContent>
</Card>
);
};
// Apply the preset style to the cards in child, if not specified //
const ProjectGrid: React.FC<Props> = ({ projects }) => {
const { t } = useTranslation("home");
return (
<Grid container md={12}>
{/* <CustomSearchForm applySearch={applySearch} fields={InputFields}/> */}
{/* item count = {items?.length??"idk"} , track/tab = {props.tab} */}
<CustomCardGrid
Title={props.tab.toString()}
items={items}
cardStyle={cardLayout}
/>
{/* <CustomCardGrid Title={props.tab.toString()} rows={rows} columns={columns} columnWidth={200} items={items}/> */}
</Grid>
<Box>
<Grid container columns={{ xs: 4, sm: 8, md: 12, lg: 16 }} spacing={2}>
{projects.map((project, idx) => (
<Grid key={`${project.code}${idx}`} item xs={4}>
<Card>
<CardContent>
<Box
sx={{
display: "flex",
justifyContent: "flex-end",
marginBlockEnd: 1,
}}
>
<Chip
size="small"
label={project.projectStatus}
color={
project.projectStatus === "On Track"
? "success"
: "warning"
}
/>
</Box>
<Typography variant="overline">{project.code}</Typography>
<Typography
variant="h6"
sx={{
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
marginBlockEnd: 3,
}}
>
{project.name}
</Typography>
{/* Hours Spent */}
<Typography variant="subtitle2">{t("Hours Spent:")}</Typography>
<Box
sx={{
display: "flex",
justifyContent: "space-between",
alignItems: "baseline",
}}
>
<Typography variant="caption">{t("Normal")}</Typography>
<Typography>
{manhourFormatter.format(project.hoursSpent)}
</Typography>
</Box>
<Box
sx={{
display: "flex",
justifyContent: "space-between",
alignItems: "baseline",
}}
>
<Typography variant="caption">{t("(Others)")}</Typography>
<Typography>{`(${manhourFormatter.format(
project.hoursSpentOther,
)})`}</Typography>
</Box>
{/* Hours Allocated */}
<Typography variant="subtitle2" sx={{ marginBlockStart: 2 }}>
{t("Hours Allocated:")}
</Typography>
<Box
sx={{
display: "flex",
justifyContent: "space-between",
alignItems: "baseline",
}}
>
<Typography variant="caption">{t("Normal")}</Typography>
<Typography>
{manhourFormatter.format(project.hoursAllocated)}
</Typography>
</Box>
<Box
sx={{
display: "flex",
justifyContent: "space-between",
alignItems: "baseline",
}}
>
<Typography variant="caption">{t("(Others)")}</Typography>
<Typography>{`(${manhourFormatter.format(
project.hoursAllocatedOther,
)})`}</Typography>
</Box>
</CardContent>
</Card>
</Grid>
))}
</Grid>
</Box>
);
};



+ 53
- 54
src/components/UserWorkspacePage/UserWorkspacePage.tsx Parādīt failu

@@ -1,80 +1,79 @@
"use client";
import Grid from "@mui/material/Grid";
import Paper from "@mui/material/Paper";
import { useState } from "react";

import { useCallback, useState } from "react";
import { useTranslation } from "react-i18next";
import AssignedProjectGrid from "../AssignedProjectGrid/AssignedProjectGrid";
import PageTitle from "../PageTitle/PageTitle";
import { Suspense } from "react";
import Button from "@mui/material/Button";
import Stack from "@mui/material/Stack";
import { Add } from "@mui/icons-material";
import Link from "next/link";
import { t } from "i18next";
import { Modal } from "@mui/material";
import CustomModal from "../CustomModal/CustomModal";
import { Typography } from "@mui/material";
import EnterTimesheetModal from "../EnterTimesheet/EnterTimesheetModal";
import EnterLeaveModal from "../EnterLeave/EnterLeaveModal";
import ButtonGroup from "@mui/material/ButtonGroup";
import AssignedProjects from "./AssignedProjects";
import { ProjectHours } from "./UserWorkspaceWrapper";

export interface Props {
allProjects: ProjectHours[];
}

const UserWorkspacePage: React.FC = () => {
const UserWorkspacePage: React.FC<Props> = ({ allProjects }) => {
const [isTimeheetModalVisible, setTimeheetModalVisible] = useState(false);
const [isLeaveModalVisible, setLeaveModalVisible] = useState(false);
const { t } = useTranslation("home");

const handleAddTimesheetButtonClick = () => {
const handleAddTimesheetButtonClick = useCallback(() => {
setTimeheetModalVisible(true);
};
}, []);

const handleCloseTimesheetModal = () => {
const handleCloseTimesheetModal = useCallback(() => {
setTimeheetModalVisible(false);
};
}, []);

const handleAddLeaveButtonClick = () => {
const handleAddLeaveButtonClick = useCallback(() => {
setLeaveModalVisible(true);
};
}, []);

const handleCloseLeaveModal = () => {
const handleCloseLeaveModal = useCallback(() => {
setLeaveModalVisible(false);
};
}, []);

return (
<Grid container height="100vh">
<Grid item sm>
<PageTitle BigTitle={"User Workspace"} />
<div>
<Stack direction="row" justifyContent="right" flexWrap="wrap">
<Button
variant="contained"
startIcon={<Add />}
onClick={handleAddTimesheetButtonClick}
sx={{ marginRight: "2rem" }}
>
Enter Timesheet
<>
<Stack
direction="row"
justifyContent="space-between"
flexWrap="wrap"
rowGap={2}
>
<Typography variant="h4" marginInlineEnd={2}>
{t("User Workspace")}
</Typography>
<Stack
direction="row"
justifyContent="right"
flexWrap="wrap"
spacing={2}
>
<ButtonGroup variant="contained">
<Button startIcon={<Add />} onClick={handleAddTimesheetButtonClick}>
{t("Enter Time")}
</Button>
<Button
variant="contained"
startIcon={<Add />}
sx={{ marginRight: "2rem" }}
// LinkComponent={Link}
// href="/projects/create"
onClick={handleAddLeaveButtonClick}
>
Record Leave
<Button startIcon={<Add />} onClick={handleAddLeaveButtonClick}>
{t("Record Leave")}
</Button>
</Stack>
<Suspense> {/*fallback={<ProjectSearch.Loading />}>*/}</Suspense>
</div>
<EnterTimesheetModal
isOpen={isTimeheetModalVisible}
onClose={handleCloseTimesheetModal}
/>
<EnterLeaveModal
isOpen={isLeaveModalVisible}
onClose={handleCloseLeaveModal}
/>
<AssignedProjectGrid Title="Assigned Project" />
</Grid>
</Grid>
</ButtonGroup>
</Stack>
</Stack>
<EnterTimesheetModal
isOpen={isTimeheetModalVisible}
onClose={handleCloseTimesheetModal}
/>
<EnterLeaveModal
isOpen={isLeaveModalVisible}
onClose={handleCloseLeaveModal}
/>
<AssignedProjects allProjects={allProjects} />
</>
);
};



+ 65
- 0
src/components/UserWorkspacePage/UserWorkspaceWrapper.tsx Parādīt failu

@@ -0,0 +1,65 @@
import UserWorkspacePage from "./UserWorkspacePage";

export interface ProjectHours {
code: string;
name: string;
hoursSpent: number;
hoursSpentOther: number;
hoursAllocated: number;
hoursAllocatedOther: number;
projectStatus: "On Track" | "Potential Delay";
}

const mockProjectCards: ProjectHours[] = [
{
code: "M1001 (C)",
name: "Consultancy Project A",
hoursSpent: 12.75,
hoursSpentOther: 0.0,
hoursAllocated: 150.0,
hoursAllocatedOther: 30.0,
projectStatus: "On Track",
},
{
code: "M1301 (C)",
name: "Consultancy Project AAA",
hoursSpent: 4.25,
hoursSpentOther: 0.25,
hoursAllocated: 30.0,
hoursAllocatedOther: 0.0,
projectStatus: "On Track",
},
{
code: "M1354 (C)",
name: "Consultancy Project BBB",
hoursSpent: 57.0,
hoursSpentOther: 6.5,
hoursAllocated: 100.0,
hoursAllocatedOther: 20.0,
projectStatus: "On Track",
},
{
code: "M1973 (C)",
name: "Construction Project CCC",
hoursSpent: 12.75,
hoursSpentOther: 0.0,
hoursAllocated: 150.0,
hoursAllocatedOther: 30.0,
projectStatus: "Potential Delay",
},
{
code: "M2014 (T)",
name: "Consultancy Project DDD",
hoursSpent: 1.0,
hoursSpentOther: 0.0,
hoursAllocated: 10.0,
hoursAllocatedOther: 0.0,
projectStatus: "Potential Delay",
},
];

const UserWorkspaceWrapper: React.FC = () => {
return <UserWorkspacePage allProjects={mockProjectCards} />;
};

export default UserWorkspaceWrapper;

+ 1
- 1
src/components/UserWorkspacePage/index.ts Parādīt failu

@@ -1 +1 @@
export { default } from "./UserWorkspacePage";
export { default } from "./UserWorkspaceWrapper";

Notiek ielāde…
Atcelt
Saglabāt