Moved to next js ssr (with fixes)
This commit is contained in:
@@ -1,16 +1,443 @@
|
||||
'use client';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { Box, LinearProgress } from '@mui/material';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import {
|
||||
Accordion,
|
||||
AccordionDetails,
|
||||
AccordionSummary,
|
||||
Box,
|
||||
Button,
|
||||
Container,
|
||||
Divider,
|
||||
Grid2,
|
||||
LinearProgress,
|
||||
Paper,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableRow,
|
||||
Tooltip,
|
||||
Typography,
|
||||
Theme,
|
||||
} from '@mui/material';
|
||||
import { styled } from '@mui/material/styles';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
import { useParams } from 'next/navigation';
|
||||
import { ArrowBack, ExpandMore } from '@mui/icons-material';
|
||||
import AvTimerOutlinedIcon from '@mui/icons-material/AvTimer';
|
||||
import { AvailableBuildings, AvailableMods, AvailableUnits, IconUrl } from '@/src/core/api';
|
||||
import { IShortWeapon, IUnit } from '@/src/types/IUnit';
|
||||
import { IRaceUnits } from '@/src/types/IUnitShort';
|
||||
import { IRaceBuildings } from '@/src/types/IBuildingShort';
|
||||
import '@/src/css/Unit.css';
|
||||
import ArmorType from '@/src/classes/ArmorType';
|
||||
import Sergeant from '@/src/classes/Sergeant';
|
||||
import WeaponSlot from '@/src/classes/WeaponSlot';
|
||||
import UnitsTable from '@/src/classes/UnitsTable';
|
||||
import { IMod } from '@/src/types/Imod';
|
||||
import Vision from '@/src/classes/Vision';
|
||||
import Required from '@/src/classes/Required';
|
||||
import { AffectedResearches } from '@/src/classes/building/Research';
|
||||
import { ModifiersProvidesTable } from '@/src/classes/ModifiersProvideTable';
|
||||
import Ability from '@/src/classes/Ability';
|
||||
import DeathExplosion from '@/src/classes/DeathExplosion';
|
||||
import Jump from '@/src/classes/Jump';
|
||||
import { DescriptionBox } from '@/src/commons/DescriptionBox';
|
||||
import { BackButton } from '@/src/commons/BackButton';
|
||||
|
||||
const UnitPageLegacy = dynamic(() => import('@/src/legacy-pages/UnitPage'), {
|
||||
ssr: false,
|
||||
loading: () => (
|
||||
<Box sx={{ display: 'flex', justifyContent: 'center', py: 8 }}>
|
||||
<LinearProgress sx={{ width: '200px' }} />
|
||||
const SectionTitle = styled(Typography)(({ theme }) => ({
|
||||
fontWeight: 700,
|
||||
mb: 2,
|
||||
fontSize: '1.25rem',
|
||||
}));
|
||||
|
||||
const StatsPaper = styled(Paper)(({ theme }) => ({
|
||||
background: theme.palette.mode === 'dark'
|
||||
? 'linear-gradient(145deg, #1a1a2e 0%, #16213e 100%)'
|
||||
: 'linear-gradient(145deg, #ffffff 0%, #f5f5f5 100%)',
|
||||
border: `1px solid ${theme.palette.mode === 'dark' ? 'rgba(255, 255, 255, 0.1)' : 'rgba(0, 0, 0, 0.1)'}`,
|
||||
borderRadius: '12px',
|
||||
overflow: 'hidden',
|
||||
'& .MuiTableBody .MuiTableRow-root': {
|
||||
'&:last-child td, &:last-child th': { border: 0 },
|
||||
},
|
||||
'& .MuiTableBody .MuiTableRow-root .MuiTableCell-head': {
|
||||
color: theme.palette.mode === 'dark' ? '#dee2e6' : 'rgba(0, 0, 0, 0.85)',
|
||||
fontWeight: 600,
|
||||
},
|
||||
}));
|
||||
|
||||
const SergeantAccordion = styled(Accordion)(({ theme }) => ({
|
||||
background: theme.palette.mode === 'dark'
|
||||
? 'linear-gradient(145deg, #1a1a2e 0%, #16213e 100%)'
|
||||
: 'linear-gradient(145deg, #ffffff 0%, #f5f5f5 100%)',
|
||||
border: `1px solid ${theme.palette.mode === 'dark' ? 'rgba(255, 255, 255, 0.1)' : 'rgba(0, 0, 0, 0.1)'}`,
|
||||
borderRadius: '12px',
|
||||
mb: 1,
|
||||
'&:before': { display: 'none' },
|
||||
'&.Mui-expanded': { margin: '0 0 8px 0' },
|
||||
}));
|
||||
|
||||
const StyledDivider = styled(Divider)(({ theme }) => ({
|
||||
my: 3,
|
||||
borderColor: theme.palette.mode === 'dark' ? 'rgba(255, 255, 255, 0.1)' : 'rgba(0, 0, 0, 0.1)',
|
||||
}));
|
||||
|
||||
const UnitTitle = styled(Typography)(({ theme }) => ({
|
||||
fontWeight: 800,
|
||||
mb: 1,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 2,
|
||||
}));
|
||||
|
||||
const UnitSubtitle = styled(Typography)(({ theme }) => ({
|
||||
color: theme.palette.text.secondary,
|
||||
fontWeight: 500,
|
||||
}));
|
||||
|
||||
function Unit(unit: IUnit, mod: IMod, theme: Theme, racesUnits: IRaceUnits[], racesBuildings: IRaceBuildings[]) {
|
||||
const isDark = theme.palette.mode === 'dark';
|
||||
|
||||
const morale = (unit.moraleMax !== null) ? <span>
|
||||
<img style={{ verticalAlign: "top" }} src="/images/ARM_Morale.webp" /> {unit.moraleMax}
|
||||
+{unit.moraleRegeneration}/s
|
||||
{unit.moraleDeathPenalty > 0 && <span> <img style={{ verticalAlign: "top" }}
|
||||
src="/images/Kills_icon.webp" /> -{unit.moraleDeathPenalty}</span>}
|
||||
</span> : "-"
|
||||
|
||||
let mapWithUnitWeapons: Map<number, Map<number, IShortWeapon>> = new Map();
|
||||
|
||||
unit.weapons.forEach(weapon => {
|
||||
const weaponMap = mapWithUnitWeapons.get(weapon.hardpoint)
|
||||
if (weaponMap == null) {
|
||||
const weaponMap = new Map()
|
||||
weaponMap.set(weapon.hardpointOrder, weapon.weapon)
|
||||
mapWithUnitWeapons.set(weapon.hardpoint, weaponMap)
|
||||
} else {
|
||||
weaponMap.set(weapon.hardpointOrder, weapon.weapon)
|
||||
}
|
||||
})
|
||||
|
||||
type sergeantProps = {
|
||||
name: string
|
||||
icon: String
|
||||
canDetect: Boolean
|
||||
}
|
||||
|
||||
const SergeantShort = (props: sergeantProps) => {
|
||||
return (
|
||||
<span style={{ fontSize: 20, color: isDark ? '#dee2e6' : 'rgba(0, 0, 0, 0.85)', display: 'flex', alignItems: 'center' }}>
|
||||
{props.icon && <img className="sergeantIcon" src={IconUrl + props.icon.replaceAll('\\', '/')} />}
|
||||
{props.name}
|
||||
{props.canDetect && <span> <img style={{ verticalAlign: "top" }}
|
||||
src="/images/DETECT_YES.webp" /></span>}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Box sx={{ mb: 3 }}>
|
||||
<UnitTitle variant="h4">
|
||||
{unit.icon &&
|
||||
<img className="unitIcon" src={IconUrl + unit.icon.replaceAll('\\', '/')} />}
|
||||
{unit.name}
|
||||
</UnitTitle>
|
||||
<UnitSubtitle variant="subtitle1">
|
||||
{mod.name} ({mod.version})
|
||||
</UnitSubtitle>
|
||||
</Box>
|
||||
|
||||
<Grid2 container spacing={3}>
|
||||
<Grid2 size={{ xs: 12, md: 4 }}>
|
||||
<StatsPaper>
|
||||
<Table size="small" aria-label="a dense table">
|
||||
<TableBody id="unit-stats-table">
|
||||
<TableRow>
|
||||
<TableCell component="th" scope="row" >Cost</TableCell>
|
||||
<TableCell>
|
||||
{unit.buildCostRequisition > 0 &&
|
||||
<span> <img style={{ verticalAlign: "top" }}
|
||||
src="/images/Resource_requisition.gif" />
|
||||
{unit.buildCostRequisition.toFixed(0)}</span>}
|
||||
{unit.buildCostPower > 0 && <span> <img style={{ verticalAlign: "top" }}
|
||||
src="/images/Resource_power.gif" />
|
||||
{unit.buildCostPower.toFixed(0)}</span>}
|
||||
{(unit.buildCostPopulation !== undefined && unit.buildCostPopulation > 0) &&
|
||||
<span> <img style={{ verticalAlign: "top" }}
|
||||
src="/images/Resource_orksquadcap.gif" />
|
||||
{unit.buildCostPopulation.toFixed(0)}</span>}
|
||||
{(unit.buildCostFaith !== undefined && unit.buildCostFaith > 0) &&
|
||||
<span> <img style={{ verticalAlign: "top" }}
|
||||
src="/images/Resource_faith.gif" />
|
||||
{unit.buildCostFaith}</span>}
|
||||
{(unit.buildCostSouls !== undefined && unit.buildCostSouls > 0) &&
|
||||
<span> <img style={{ verticalAlign: "top" }}
|
||||
src="/images/Resource_souls.gif" />
|
||||
{unit.buildCostSouls.toFixed(0)}</span>}
|
||||
{unit.capInfantry > 0 && <span> <img style={{ verticalAlign: "top" }}
|
||||
src="/images/Resource_cap_infantry.gif" />
|
||||
{unit.capInfantry}</span>}
|
||||
{unit.capSupport > 0 && <span> <img style={{ verticalAlign: "top" }}
|
||||
src="/images/Resource_cap_vehicle.gif" />
|
||||
{unit.capSupport}</span>}
|
||||
{(unit.buildCostTime !== undefined && unit.buildCostTime > 0) &&
|
||||
<span> <AvTimerOutlinedIcon
|
||||
style={{ verticalAlign: "top", fontSize: "18px" }} />
|
||||
{unit.buildCostTime}s</span>}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
{(unit?.reinforceTime !== 0 && unit.reinforceTime !== null && unit.squadMaxSize > 1) &&
|
||||
<TableRow>
|
||||
<TableCell>Reinforce cost</TableCell>
|
||||
<TableCell>
|
||||
{unit.reinforceCostRequisition && unit.reinforceCostRequisition > 0 ?
|
||||
<span> <img style={{ verticalAlign: "top" }}
|
||||
src="/images/Resource_requisition.gif" />
|
||||
{unit.reinforceCostRequisition.toFixed(0)}</span> : <span />}
|
||||
{unit.reinforceCostPower !== undefined && unit.reinforceCostPower > 0 &&
|
||||
<span> <img style={{ verticalAlign: "top" }}
|
||||
src="/images/Resource_power.gif" />
|
||||
{unit.reinforceCostPower.toFixed(0)}</span>}
|
||||
{(unit.reinforceCostPopulation !== undefined && unit.reinforceCostPopulation > 0) &&
|
||||
<span> <img style={{ verticalAlign: "top" }}
|
||||
src="/images/Resource_orksquadcap.gif" />
|
||||
{unit.reinforceCostPopulation.toFixed(0)}</span>}
|
||||
{(unit.reinforceCostFaith !== undefined && unit.reinforceCostFaith > 0) &&
|
||||
<span> <img style={{ verticalAlign: "top" }}
|
||||
src="/images/Resource_faith.gif" />
|
||||
{unit.reinforceCostFaith}</span>}
|
||||
{(unit.reinforceCostSouls !== undefined && unit.reinforceCostSouls > 0) &&
|
||||
<span> <img style={{ verticalAlign: "top" }}
|
||||
src="/images/Resource_souls.gif" />
|
||||
{unit.reinforceCostSouls.toFixed(0)}</span>}
|
||||
{(unit.reinforceTime !== undefined && unit.reinforceTime > 0) &&
|
||||
<span> <AvTimerOutlinedIcon
|
||||
style={{ verticalAlign: "top", fontSize: "18px" }} />
|
||||
{unit.reinforceTime}s</span>}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
}
|
||||
{(unit.requisitionIncome !== undefined && unit.requisitionIncome !== null || unit.powerIncome !== undefined && unit.powerIncome !== null || unit.faithIncome !== undefined && unit.faithIncome !== null) &&
|
||||
<TableRow>
|
||||
<TableCell >Resource income</TableCell>
|
||||
<TableCell>
|
||||
{unit.requisitionIncome !== undefined && unit.requisitionIncome > 0 &&
|
||||
<span> <img style={{ verticalAlign: "top" }}
|
||||
src="/images/Resource_requisition.gif" />
|
||||
{unit.requisitionIncome}</span>}
|
||||
{unit.powerIncome !== undefined && unit.powerIncome > 0 &&
|
||||
<span> <img style={{ verticalAlign: "top" }}
|
||||
src="/images/Resource_power.gif" />
|
||||
{unit.powerIncome}</span>}
|
||||
{unit.faithIncome !== undefined && unit.faithIncome > 0 &&
|
||||
<span> <img style={{ verticalAlign: "top" }}
|
||||
src="/images/Resource_faith.gif" />
|
||||
{unit.faithIncome}</span>}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
}
|
||||
{unit.squadMaxSize > 1 &&
|
||||
<TableRow>
|
||||
<TableCell >Squad size</TableCell>
|
||||
<TableCell>{unit.squadStartSize} / {unit.squadMaxSize}</TableCell>
|
||||
</TableRow>
|
||||
}
|
||||
<TableRow>
|
||||
<TableCell >Armor type</TableCell>
|
||||
<TableCell>
|
||||
{unit.armorType2 == null ? <ArmorType name={unit.armorType.name} compact={false} /> : <Tooltip title={"upgrade/debuff can turns to " + unit.armorType2.name}><span><ArmorType name={unit.armorType.name} compact={false} /></span></Tooltip>}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell >Health</TableCell>
|
||||
<TableCell>
|
||||
<img style={{ verticalAlign: "top" }}
|
||||
src="/images/Health_icon.webp" />
|
||||
{unit.health} {unit.healthRegeneration > 0 &&
|
||||
<span>+{unit.healthRegeneration}/s</span>}
|
||||
{unit.armour !== undefined && unit.armour !== 0 && <span><img style={{ height: 20, verticalAlign: "top" }} src="/images/defence.png" />{unit.armour} </span>}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell >Move speed</TableCell>
|
||||
<TableCell>{unit.moveSpeed}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell >Morale</TableCell>
|
||||
<TableCell>{morale}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell >Mass</TableCell>
|
||||
<TableCell>{unit.mass}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow sx={{ '&:last-child td, &:last-child th': { border: 0 } }}>
|
||||
<TableCell >Vision</TableCell>
|
||||
<TableCell><Vision sight={unit.sightRadius} detect={unit.detectRadius} /></TableCell>
|
||||
</TableRow>
|
||||
{unit.repairMax !== undefined && unit.repairMax !== null &&
|
||||
<TableRow sx={{ '&:last-child td, &:last-child th': { border: 0 } }}>
|
||||
<TableCell >Repair max</TableCell>
|
||||
<TableCell>{unit.repairMax}</TableCell>
|
||||
</TableRow>
|
||||
}
|
||||
{unit.repairSpeed !== undefined && unit.repairSpeed !== null && unit.repairCostPercent !== null &&
|
||||
<TableRow sx={{ '&:last-child td, &:last-child th': { border: 0 } }}>
|
||||
<TableCell >Repair</TableCell>
|
||||
<TableCell>{unit.repairSpeed} hp/s; {unit.repairCostPercent}% cost</TableCell>
|
||||
</TableRow>
|
||||
}
|
||||
{unit.mobValue != null &&
|
||||
<TableRow sx={{ '&:last-child td, &:last-child th': { border: 0 } }}>
|
||||
<TableCell >Mob value</TableCell>
|
||||
<TableCell><span> <img style={{ height: 20, verticalAlign: "top" }} src="/images/Mob_bonus.gif" /> {unit.mobValue} </span></TableCell>
|
||||
</TableRow>
|
||||
}
|
||||
{unit.squadLimit !== undefined && unit.squadLimit !== null &&
|
||||
<TableRow sx={{ '&:last-child td, &:last-child th': { border: 0 } }}>
|
||||
<TableCell >Limit</TableCell>
|
||||
<TableCell>{unit.squadLimit}</TableCell>
|
||||
</TableRow>
|
||||
}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</StatsPaper>
|
||||
</Grid2>
|
||||
<Grid2 size={{ xs: 12, md: 8 }}>
|
||||
<DescriptionBox>
|
||||
{unit.description}
|
||||
</DescriptionBox>
|
||||
</Grid2>
|
||||
{unit.requirements !== null &&
|
||||
<Grid2 size={{ xs: 12, md: 12 }}>
|
||||
<Required requirement={unit.requirements} modId={unit.modId} raceId={unit.race.id} />
|
||||
</Grid2>}
|
||||
<Grid2 size={12}>
|
||||
{unit.sergeants.map(s =>
|
||||
<SergeantAccordion key={s.id} TransitionProps={{ unmountOnExit: true, timeout: 100 }}>
|
||||
<AccordionSummary
|
||||
sx={{ color: isDark ? '#dee2e6' : 'rgba(0, 0, 0, 0.85)', '& .MuiAccordionSummary-content': { margin: '12px 0' }, '& .MuiAccordionSummary-content.Mui-expanded': { margin: '12px 0' } }}>
|
||||
<SergeantShort name={s.name} icon={s.icon} canDetect={s.detectRadius > 0} />
|
||||
</AccordionSummary>
|
||||
<AccordionDetails sx={{ color: theme.palette.text.primary }}>
|
||||
<Sergeant mod={mod} sergeant={s} race={unit.race} />
|
||||
</AccordionDetails>
|
||||
</SergeantAccordion>)}
|
||||
</Grid2>
|
||||
|
||||
{unit.moraleMax !== null && !(unit.moraleBrakeModifiers.find(m => m.reference.includes("accuracy_weapon_modifier") && m.value === 0.2) !== undefined &&
|
||||
unit.moraleBrakeModifiers.find(m => m.reference.includes("speed_maximum_modifier") && m.value === 1.2) !== undefined &&
|
||||
unit.moraleBrakeModifiers.length === 2)
|
||||
&& <Grid2 size={12}>
|
||||
<SectionTitle><img style={{ verticalAlign: "top" }} src="/images/ARM_Morale.webp" /> Morale broken <img style={{ verticalAlign: "top" }} src="/images/ARM_Morale.webp" /></SectionTitle>
|
||||
<ModifiersProvidesTable modifiers={unit.moraleBrakeModifiers} modId={unit.modId} race={unit.race} affectedData={unit.affectedData} />
|
||||
</Grid2>}
|
||||
|
||||
{unit.modifiers.length > 0 && <Grid2 size={12}>
|
||||
<SectionTitle>Affected on</SectionTitle>
|
||||
<ModifiersProvidesTable modifiers={unit.modifiers} modId={unit.modId} race={unit.race} affectedData={unit.affectedData} />
|
||||
</Grid2>}
|
||||
|
||||
{unit.abilities.length > 0 && <Grid2 size={12}>
|
||||
<SectionTitle>Abilities</SectionTitle>
|
||||
{unit.abilities.map(a =>
|
||||
<Ability mod={mod} ability={a} race={unit.race} />
|
||||
)}
|
||||
</Grid2>}
|
||||
|
||||
{unit.jumps != null && <Grid2 size={12}>
|
||||
<Jump jumps={unit.jumps} race={unit.race} mod={mod} />
|
||||
</Grid2>}
|
||||
|
||||
<Grid2 size={12}>
|
||||
{[...mapWithUnitWeapons.keys()].sort(function (a, b) {
|
||||
return a - b;
|
||||
}).map(h => <WeaponSlot haveReinforceMenu={unit.haveReinforceMenu} key={h} race={unit.race} mod={mod} unitWeapons={mapWithUnitWeapons.get(h)} hardpoint={h} />)}
|
||||
</Grid2>
|
||||
{unit.deathExplosions.length > 0 &&
|
||||
<Grid2 size={12}>
|
||||
{unit.deathExplosions.map(da =>
|
||||
<DeathExplosion deathExplosion={da} mod={mod} />
|
||||
)}
|
||||
</Grid2>
|
||||
}
|
||||
<Grid2 size={12}>
|
||||
<AffectedResearches researches={unit.affectedResearches} modId={mod.id} raceId={unit.race.id} />
|
||||
</Grid2>
|
||||
</Grid2>
|
||||
|
||||
<Box sx={{ mt: 3, mb: 2, fontWeight: 600, fontSize: '0.85rem' }}>
|
||||
Hotkey: {unit.hotkey} <span style={{ fontSize: '12px', fontWeight: 400, color: 'rgba(128,128,128,0.7)' }}>Filename: {unit.filename}</span>
|
||||
</Box>
|
||||
<StyledDivider />
|
||||
<UnitsTable modId={mod.id} racesUnits={racesUnits} racesBuildings={racesBuildings} />
|
||||
</Box>
|
||||
),
|
||||
});
|
||||
)
|
||||
}
|
||||
|
||||
export default function UnitPageClient() {
|
||||
return <UnitPageLegacy />;
|
||||
export default function UnitPageClient({
|
||||
initialUnit,
|
||||
initialMod,
|
||||
}: {
|
||||
initialUnit: IUnit | null;
|
||||
initialMod: IMod | null;
|
||||
}) {
|
||||
const params = useParams() as Record<string, string>;
|
||||
const { modId, raceId, unitId } = params;
|
||||
const theme = useTheme();
|
||||
const [unit, setUnit] = useState<IUnit | null>(initialUnit);
|
||||
const [mod, setMod] = useState<IMod | null>(initialMod);
|
||||
const [racesUnits, setRacesUnits] = useState<IRaceUnits[]>([]);
|
||||
const [racesBuildings, setRacesBuildings] = useState<IRaceBuildings[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
if (unit == null) {
|
||||
fetch(AvailableUnits + "/" + unitId)
|
||||
.then(res => res.json())
|
||||
.then((res: IUnit) => { if (!cancelled) setUnit(res); });
|
||||
}
|
||||
if (mod == null) {
|
||||
fetch(AvailableMods + "/" + modId)
|
||||
.then(res => res.json())
|
||||
.then((res: IMod) => { if (!cancelled) setMod(res); });
|
||||
}
|
||||
fetch(AvailableUnits + "/mod/" + modId)
|
||||
.then(res => res.json())
|
||||
.then((resUnits: IRaceUnits[]) => {
|
||||
if (cancelled) return;
|
||||
setRacesUnits(resUnits);
|
||||
if (resUnits.length <= 10) {
|
||||
fetch(AvailableBuildings + "/mod/" + modId)
|
||||
.then(res => res.json())
|
||||
.then((resBuildings: IRaceBuildings[]) => {
|
||||
if (!cancelled) setRacesBuildings(resBuildings);
|
||||
});
|
||||
}
|
||||
});
|
||||
return () => { cancelled = true; };
|
||||
}, [modId, raceId, unitId]);
|
||||
|
||||
if (unit != null && mod != null) {
|
||||
const backRef = "/mod/" + modId + "/race/" + raceId;
|
||||
|
||||
return (
|
||||
<Container maxWidth="lg">
|
||||
<BackButton
|
||||
variant="outlined"
|
||||
startIcon={<ArrowBack />}
|
||||
href={backRef}
|
||||
>
|
||||
Back to race
|
||||
</BackButton>
|
||||
{Unit(unit, mod, theme, racesUnits, racesBuildings)}
|
||||
</Container>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<Box sx={{ display: 'flex', justifyContent: 'center', py: 8 }}>
|
||||
<LinearProgress sx={{ width: '200px' }} />
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user