'use client';
import React from 'react';
import {
Accordion,
AccordionDetails,
AccordionSummary,
Box,
Container,
Divider,
Grid2,
Link,
List,
ListItem,
Paper,
Typography,
Theme,
} from '@mui/material';
import { styled } from '@mui/material/styles';
import { useTheme } from '@mui/material/styles';
import { ArrowBack, ExpandMore } from '@mui/icons-material';
import { IconUrl } from '@/src/core/api';
import { IMod } from '@/src/types/Imod';
import { Irace } from '@/src/types/Irace';
import '@/src/css/Unit.css';
import { IRaceUnits, IUnitShort } from '@/src/types/IUnitShort';
import { IBuildingShort, IRaceBuildings } from '@/src/types/IBuildingShort';
import { StyledLink } from '@/src/commons/StyledLink';
import { BackButton } from '@/src/commons/BackButton';
const SectionTitle = styled(Typography)(({ theme }) => ({
fontWeight: 700,
mb: 2,
fontSize: '1.25rem',
}));
const UnitCard = 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: '16px',
transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',
'&:hover': {
boxShadow: theme.palette.mode === 'dark' ? '0 20px 40px rgba(255, 255, 255, 0.1)' : '0 20px 40px rgba(0, 0, 0, 0.2)',
borderColor: theme.palette.mode === 'dark' ? 'rgba(255, 255, 255, 0.3)' : 'rgba(0, 0, 0, 0.3)',
},
}));
const BuildingCard = styled(UnitCard)(({ theme }) => ({
padding: theme.spacing(1),
}));
const UnitLink = styled(Link)(({ theme }) => ({
color: theme.palette.text.primary,
textDecoration: 'none',
display: 'block',
'&:hover': { color: theme.palette.mode === 'dark' ? '#dee2e6' : 'rgba(0, 0, 0, 0.85)' }
}));
const LoadingText = styled(Typography)(({ theme }) => ({
color: theme.palette.text.secondary,
}));
function Unit(unit: IUnitShort, modId: number, raceId: string, theme: Theme) { const isDark = theme.palette.mode === 'dark';
return (
{unit.icon &&
}
{unit.name}
{unit.canDetect &&
}
)
}
function UnitSmall(unit: IUnitShort, modId: number, raceId: string) {
var unitName = ""
if (unit.name.length > 21) {
unitName = unit.name.substring(0, 19) + "...";
} else {
unitName = unit.name;
}
return (
{unit.icon &&
}
{unitName}
{unit.canDetect &&
}
)
}
function Building(building: IBuildingShort, modId: number, raceId: string, theme: Theme) {
const isDark = theme.palette.mode === 'dark';
return (
{building.icon &&
}
{building.name}
{building.canDetect &&
}
{building.units.map(unit => UnitSmall(unit, modId, raceId))}
)
}
interface UnitsProps {
raceId: string;
modId: number;
units: IRaceUnits | null;
buildings: IRaceBuildings | null;
}
function Units({ raceId, modId, units, buildings }: UnitsProps) {
const theme = useTheme();
const isDark = theme.palette.mode === 'dark';
if (units) {
const accordionSx = isDark ? {
background: 'linear-gradient(145deg, #1a1a2e 0%, #16213e 100%)',
border: '1px solid rgba(255, 255, 255, 0.1)',
borderRadius: '12px',
'&:before': { display: 'none' },
'&.Mui-expanded': { margin: '0 0 8px 0' },
} : {
background: 'linear-gradient(145deg, #ffffff 0%, #f5f5f5 100%)',
border: '1px solid rgba(0, 0, 0, 0.1)',
borderRadius: '12px',
'&:before': { display: 'none' },
'&.Mui-expanded': { margin: '0 0 8px 0' },
};
return (buildings != null ?
{buildings.buildings.map(building => Building(building, modId, raceId, theme))}
{buildings.buildingsAdvanced.length > 0 &&
Advanced buildings
{buildings.buildingsAdvanced.map(building => Building(building, modId, raceId, theme))}
}
}
aria-controls="units-accordion"
id="units-accordion"
sx={{ color: isDark ? '#dee2e6' : 'rgba(0, 0, 0, 0.85)', '& .MuiAccordionSummary-content': { margin: '12px 0' }, '& .MuiAccordionSummary-content.Mui-expanded': { margin: '12px 0' } }}
>
All units
Infantry
{units.infantry.map(unit => Unit(unit, modId, raceId, theme))}
Tech
{units.tech.map(unit => Unit(unit, modId, raceId, theme))}
Support
{units.support.map(unit => Unit(unit, modId, raceId, theme))}
: Loading
)
} else {
return Loading...;
}
}
interface RacePageClientProps {
initialMod: IMod | null;
initialRace: Irace | null;
raceUnits: IRaceUnits | null;
raceBuildings: IRaceBuildings | null;
}
export default function RacePageClient({ initialMod, initialRace, raceUnits, raceBuildings }: RacePageClientProps) {
const theme = useTheme();
if (initialMod != null && initialRace != null) {
const backRef = "/mod/" + initialMod.id;
const isDark = theme.palette.mode === 'dark';
return (
}
href={backRef}
>
Back to mod
{initialRace.name}
{initialMod.name} ({initialMod.version})
);
} else {
return (
Race not found
);
}
}