Skip to content

Commit

Permalink
Merge pull request #30 from Sports-day/feature/#28-add-team-details-d…
Browse files Browse the repository at this point in the history
…isplay

チームの情報を表示する画面の実装
  • Loading branch information
Takkun0310 authored May 13, 2024
2 parents 6b45633 + 59ab1d2 commit 5fa7c8d
Show file tree
Hide file tree
Showing 3 changed files with 210 additions and 1 deletion.
35 changes: 35 additions & 0 deletions app/(authenticated)/teams/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Breadcrumbs, Link, Stack, Typography} from "@mui/material";
import CardBackground from "@/components/layout/cardBackground";
import React from "react";
import {teamFactory} from "@/src/models/TeamModel";
import TeamEditor from "@/components/teams/teamEditor";
import {classFactory} from "@/src/models/ClassModel";

export default async function TeamDetailPage({ params }: { params: { id: string } }) {
const teamId = parseInt(params.id, 10)
const teamInfo = await teamFactory().show(teamId)
const classes = await classFactory().show(teamInfo.classId)
const teamUsers = await teamFactory().getTeamUsers(teamId);

return (
<Stack spacing={1} mx={2} my={3}>
<Breadcrumbs aria-label="breadcrumb" sx={{pl: 2}}>
<Link underline="hover" color="inherit" href="/">
管理者のダッシュボード
</Link>
<Link underline="hover" color="inherit" href="/teams/">
チーム管理
</Link>
<Typography color="text.primary">{teamInfo.name}</Typography>
</Breadcrumbs>

<CardBackground title={`${teamInfo.name} の情報`}>
<TeamEditor
team={teamInfo}
teamUser={teamUsers}
class={classes}
/>
</CardBackground>
</Stack>
)
}
161 changes: 161 additions & 0 deletions components/teams/teamEditor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
'use client'
import {
Box,
Button,
FormControl, InputLabel, Paper,
Stack, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, TextField,
Typography
} from "@mui/material";
import {HiCheck, HiTrash} from "react-icons/hi2";
import React, {useState} from "react";
import {useRouter} from "next/navigation";
import {Team, teamFactory} from "@/src/models/TeamModel";
import {Class} from "@/src/models/ClassModel";
import {User} from "@/src/models/UserModel";

type TeamEditorProps = {
class : Class;
team : Team;
teamUser : User[];
}

export default function TeamEditor(props: TeamEditorProps) {
const router = useRouter()
const [teamName, setTeamName] = useState<string>(props.team.name)

const handleSubmit = async () => {
await teamFactory().update(props.team.id, {
name: teamName,
description: props.team.description,
classId: props.team.classId,
teamTagId: props.team.teamTagId
})

router.push('/teams')
router.refresh()

}

return (
<>
<Stack mx={0} my={2} spacing={2} direction={"column"}>
<Stack
direction={"row"}
spacing={2}
alignItems={"center"}
>
<FormControl fullWidth>
<TextField
label="チーム名"
id="change-team-name"
InputLabelProps={{ shrink: true }}
defaultValue={props.team.name}
value={teamName}
onChange={(t) => {
setTeamName(t.target.value)
}}
/>
</FormControl>
</Stack>

<FormControl fullWidth>
<Paper variant="outlined" sx={{
p: 2,
minWidth: 'fit-content',
position: 'relative',
border: '1px solid #adafbd',
display: 'inline-block'
}}>
<InputLabel
id="class-select-label"
variant="standard"
sx={{
position: 'absolute',
top: 0,
left: -8,
bgcolor: 'background.paper',
px: 1,
transform: 'translate(14px, -8px) scale(1)',
fontSize: '12px'
}}
>
所属クラス
</InputLabel>
<Typography variant="body1" >
{props.class.name}
</Typography>
</Paper>
</FormControl>

<FormControl fullWidth>
<Box sx={{ position: 'relative' }}>
<InputLabel sx={{
position: 'absolute',
top: '-24px',
left: '-6px',
bgcolor: 'background.paper',
px: 1,
fontSize: '12px'
}}>
チームメンバー
</InputLabel>
</Box>
<TableContainer
component={Paper}
elevation={0}
sx={{ border: '1px solid #adafbd' }}
>
<Table>
<TableHead sx={{ borderBottom: '1px solid #adafbd' }}>
<TableRow>
<TableCell sx={{ border: 0 }}>学籍番号</TableCell>
<TableCell sx={{ border: 0 }}>名前</TableCell>
<TableCell sx={{ border: 0 }}>性別</TableCell>
</TableRow>
</TableHead>
<TableBody>
{props.teamUser.map((member) => {
return (
<TableRow key={member.id}>
<TableCell sx={{ border: 0 }}>{member.id}</TableCell>
<TableCell sx={{ border: 0 }}>{member.name}</TableCell>
<TableCell sx={{ border: 0 }}>
<Typography
sx={{ color: member.gender === "female" ? "red" : "inherit" }}
>
{member.gender === "male" ? "男性" : "女性"}
</Typography>
</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
</TableContainer>
</FormControl>

<Stack
direction={"row"}
my={0.5}
spacing={1}
width={"100%"}
justifyContent={"space-between"}
alignItems="center"
>
<Button variant="outlined" color={"error"} startIcon={<HiTrash/>}>
このチームを削除
</Button>
<Button
variant={"contained"}
color={"info"}
sx={{flexGrow: 3}}
startIcon={<HiCheck/>}
onClick={handleSubmit}
>
保存
</Button>
</Stack>
</Stack>
</>
)
}
15 changes: 14 additions & 1 deletion components/teams/teamsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import {AgGridReact} from 'ag-grid-react';
import "ag-grid-community/styles/ag-grid.css"; // Mandatory CSS required by the grid
import "ag-grid-community/styles/ag-theme-quartz.css"; // Optional Theme applied to the grid

import {ColDef, ModuleRegistry} from 'ag-grid-community';
import {ColDef, ModuleRegistry, RowClickedEvent} from 'ag-grid-community';
import {ClientSideRowModelModule} from 'ag-grid-community';
import {Team} from "@/src/models/TeamModel";
import {Class} from '@/src/models/ClassModel';
import {TeamTag} from "@/src/models/TeamTagModel";
import {useRouter} from "next/navigation";

ModuleRegistry.registerModules([ClientSideRowModelModule]);

Expand All @@ -30,6 +31,7 @@ type IRow = {
// Create new GridExample component
const TeamsAgGrid = (props: TeamsAgGridProps) => {
const height = 'calc(100vh - 230px)';
const router = useRouter()
// Row Data: The data to be displayed.
const [rowData, setRowData] = useState<IRow[]>([]);

Expand Down Expand Up @@ -60,13 +62,24 @@ const TeamsAgGrid = (props: TeamsAgGridProps) => {
[props.classes, props.teams, props.teamTags]
)

const handleRowClick = (e: RowClickedEvent<IRow>) => {
const data = e.data

// ignore undefined
if (!data) return

// redirect
router.push(`/teams/${data.teamId}`)
}


// Container: Defines the grid's theme & dimensions.
return (
<div className={"ag-theme-quartz"} style={{width: '100%', height: height, borderRadius: "10px"}}>
<AgGridReact
rowData={rowData}
columnDefs={colDefs}
onRowClicked={handleRowClick}
/>
</div>
);
Expand Down

0 comments on commit 5fa7c8d

Please sign in to comment.