Soulstorm-wiki-frontend/src/pages/RacePageFast.tsx
2025-08-18 13:02:10 +03:00

214 lines
7.5 KiB
TypeScript

import {AvailableBuildings, AvailableMods, AvailableRacesPart, AvailableUnits, IconUrl} from "../core/api";
import React, {useState} from "react";
import {withRouter} from "../core/withrouter";
import {IMod} from "../types/Imod";
import {Irace} from "../types/Irace";
import '../css/Unit.css'
import {
Accordion,
AccordionDetails,
AccordionSummary,
Button,
ButtonGroup,
Grid2, Link,
List,
ListItem,
ListSubheader,
Paper,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
ToggleButton,
ToggleButtonClassKey,
ToggleButtonGroup,
Typography
} from "@mui/material";
import {ArrowBack, ArrowDropDown, ExpandMore} from "@mui/icons-material";
import ArmorType from "../classes/ArmorType";
import Weapon from "../classes/Weapon";
import {IRaceUnits, IUnitShort} from "../types/IUnitShort";
import {IBuildingShort, IRaceBuildings} from "../types/IBuildingShort";
interface RacePageState {
mod: IMod,
race: Irace,
units: IUnitShort[],
}
function Unit (unit: IUnitShort, modId: number, raceId: String) {
return (<Link href={"/mod/" + modId + "/race/" + raceId + "/unit/" + unit.id}><ListItem>
{unit.icon && <img className="unitIcon" src={IconUrl + unit.icon.replaceAll('\\', '/')}/> }
{unit.name}
{unit.canDetect && <span>&nbsp;<img style={{verticalAlign: "top"}}
src="/images/DETECT_YES.webp"/></span>}
</ListItem></Link>)
}
function UnitSmall (unit: IUnitShort, modId: number, raceId: String) {
var unitName = ""
if (unit.name.length > 21) {
unitName = unit.name.substring(0, 20) + "...";
} else {
unitName = unit.name;
}
return (<Link href={"/mod/" + modId + "/race/" + raceId + "/unit/" + unit.id}>
{unit.icon && <img className="unitIconSmall" src={IconUrl + unit.icon.replaceAll('\\', '/')}/>}
<span style={{fontSize: 12}}>{unitName}</span>
{unit.canDetect && <span>&nbsp;<img
src="/images/DETECT_YES.webp"/></span>}<br/></Link>)
}
function Building (building: IBuildingShort, modId: number, raceId: String) {
return (<Grid2 size={{xs: 12, md: 3}}><Link href={"/mod/" + modId + "/race/" + raceId + "/building/" + building.id}><ListItem>
{building.icon && <img className="unitIcon" src={IconUrl + building.icon.replaceAll('\\', '/')}/>}
{building.name}
{building.canDetect && <span>&nbsp;<img style={{verticalAlign: "top"}}
src="/images/DETECT_YES.webp"/></span>}
</ListItem></Link>
{building.units.map(unit => UnitSmall(unit, modId, raceId))}
</Grid2>)
}
interface UnitsProps{
raceId: string,
modId: number,
}
interface UnitsState {
selectedUnits: String | null,
units: IRaceUnits | null,
buildings: IRaceBuildings | null,
}
class Units extends React.Component<UnitsProps, UnitsState> {
constructor(props: any) {
super(props);
let urlUnits = AvailableUnits + "/" + this.props.modId + "/" + this.props.raceId;
fetch(urlUnits)
.then(res => res.json())
.then((res: IRaceUnits) => {
this.setState({
units: res,
})
})
let urlBuildings = AvailableBuildings + "/" + this.props.modId + "/" + this.props.raceId;
fetch(urlBuildings)
.then(res => res.json())
.then((res: IRaceBuildings) => {
this.setState({
buildings: res,
})
})
}
render () {
if (this.state && this.state.units) {
return (<div>
{this.state.units != null && this.state.buildings != null ?
<Grid2 container spacing={2}>
{this.state.buildings.buildings.map(building => Building(building, this.props.modId, this.props.raceId))}
<Grid2 size={{xs: 12, md: 12}}>
<Accordion>
<AccordionSummary
expandIcon={<ExpandMore/>}
aria-controls="units-accordion"
id="units-accordion"
>
<h3>All units</h3>
</AccordionSummary>
<AccordionDetails>
<Grid2 container spacing={2}>
<Grid2 size= {{xs: 12, md: 4}}>
<h3>Infantry</h3>
{this.state.units.infantry.map(unit => Unit(unit, this.props.modId, this.props.raceId))}
</Grid2>
<Grid2 size={{xs: 12, md: 4}}>
<h3>Tech</h3>
<List sx={{width: '100%', maxWidth: 360, bgcolor: 'background.paper'}}>
{this.state.units.tech.map(unit => Unit(unit, this.props.modId, this.props.raceId))}
</List>
</Grid2>
<Grid2 size={{xs: 12, md: 4}}>
<h3>Support</h3>
<List sx={{width: '100%', maxWidth: 360, bgcolor: 'background.paper'}}>
{this.state.units.support.map(unit => Unit(unit, this.props.modId, this.props.raceId))}
</List>
</Grid2>
</Grid2>
</AccordionDetails>
</Accordion>
</Grid2><br/>
</Grid2>
: "Loading"}
</div>)
} else {
return "Loading...";
}
}
}
class RacePageFast extends React.Component<any, RacePageState> {
constructor(props: any) {
super(props);
console.log(this.props.match.params.id);
}
async componentDidMount() {
const responseMod = await fetch(AvailableMods + "/" + this.props.match.params.modId);
const modData: IMod = await responseMod.json();
this.setState({
mod: modData
});
const response = await fetch(AvailableRacesPart + "/" + this.props.match.params.raceId);
const racesData: Irace = await response.json();
this.setState({
race : racesData
});
}
render() {
if(this.state != null && this.state.mod != null && this.state.race != null ){
const backRef = "/mod/" + this.state.mod.id
return <div><Link href={backRef}><Button id="back-button" variant="contained" startIcon={<ArrowBack/>}> Back</Button></Link>
<h1>{this.state.mod.name} ({this.state.mod.version}) - {this.state.race.name}</h1>
<Units raceId={this.state.race.id} modId={this.state.mod.id}/>
</div>;
} else {
return "loading...";
}
}
}
export default withRouter(RacePageFast);