ManagementSystem/FRONTEND/src/components/ProjectInvolvement/ProjectInvolvement.tsx

146 lines
4.0 KiB
TypeScript

import { Box, Table, Text } from '@mantine/core'
import { IconCornerDownRight } from '@tabler/icons-react'
import { useState } from 'react'
import classes from './ProjectInvolvement.module.css'
interface Project {
name: string
sprints: Sprint[]
}
interface Sprint {
name: string
criterias: TableRow[]
}
interface TableRow {
criteria: string
note: string
createdBy: string
point: number
}
interface ExpandedProjects {
[projectName: string]: boolean
}
interface ExpandedSprints {
[projectName: string]: {
[sprintName: string]: boolean
}
}
interface ProjectInvolvementProps {
dataProfile: Project[]
page: string
}
type CriteriaTableProps = {
data: TableRow[]
page: string
}
const CriteriaTable: React.FC<CriteriaTableProps> = ({ data, page }) => (
<Table striped highlightOnHover withTableBorder withColumnBorders>
<Table.Thead>
<Table.Tr bg="#228be66b">
<Table.Th style={{ textAlign: 'center', width: '25%' }}>
Criteria
</Table.Th>
<Table.Th style={{ textAlign: 'center', width: '45%' }}>Note</Table.Th>
<Table.Th style={{ textAlign: 'center', width: '20%' }}>
Created by
</Table.Th>
{page == 'profile' ? (
''
) : (
<Table.Th style={{ textAlign: 'center', width: '10%' }}>
Point
</Table.Th>
)}
</Table.Tr>
</Table.Thead>
<Table.Tbody>
{data.map((row, index) => (
<Table.Tr key={index}>
<Table.Td style={{ textAlign: 'start' }}>{row.criteria}</Table.Td>
<Table.Td style={{ textAlign: 'start' }}>{row.note}</Table.Td>
<Table.Td style={{ textAlign: 'start' }}>{row.createdBy}</Table.Td>
{page == 'profile' ? (
''
) : (
<Table.Td>{row.point == 0 ? '' : row.point}</Table.Td>
)}
</Table.Tr>
))}
</Table.Tbody>
</Table>
)
const ProjectInvolvement = ({ dataProfile, page }: ProjectInvolvementProps) => {
const [expandedProjects, setExpandedProjects] = useState<ExpandedProjects>({})
const [expandedSprints, setExpandedSprints] = useState<ExpandedSprints>({})
const handleProjectToggle = (projectName: string) => {
setExpandedProjects((prev) => ({
...prev,
[projectName]: !prev[projectName], // Toggle state for this project
}))
}
const handleSprintToggle = (projectName: string, sprintName: string) => {
setExpandedSprints((prev) => ({
...prev,
[projectName]: {
...prev[projectName],
[sprintName]: !prev[projectName]?.[sprintName], // Toggle state for this sprint
},
}))
}
return (
<Box className={classes.project} mt="lg">
{dataProfile.map((project) => (
<div key={project.name}>
<Box
className={classes.projectHeader}
onClick={() => handleProjectToggle(project.name)}
>
<Text ml="sm" fw={600}>
{project.name}
</Text>
</Box>
{expandedProjects[project.name] && (
<Box className={classes.sprintList}>
{project.sprints.map((sprint) => (
<div key={sprint.name}>
<Box
className={classes.sprintHeader}
onClick={() =>
handleSprintToggle(project.name, sprint.name)
}
>
<IconCornerDownRight size={20} />
<Text ml="xs" className={classes.sprintHeader2} fw={600}>
{sprint.name}
</Text>
</Box>
{expandedSprints[project.name]?.[sprint.name] && (
<Box className={classes.criteriaTable}>
<CriteriaTable data={sprint.criterias} page={page} />
</Box>
)}
</div>
))}
</Box>
)}
</div>
))}
</Box>
)
}
export default ProjectInvolvement