chg: usr: fix the '0' in Battle reports #6
This commit is contained in:
@@ -1,6 +1,9 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import Dialog from '@mui/material/Dialog';
|
import Dialog from '@mui/material/Dialog';
|
||||||
import { createTheme, ThemeProvider } from '@mui/material/styles';
|
import { createTheme, ThemeProvider } from '@mui/material/styles';
|
||||||
|
import Avatar from './battle-dialog/Avatar';
|
||||||
|
import StatRow from './battle-dialog/StatRow';
|
||||||
|
import BonusPoints from './battle-dialog/BonusPoints';
|
||||||
|
|
||||||
const darkTheme = createTheme({ palette: { mode: 'dark' } });
|
const darkTheme = createTheme({ palette: { mode: 'dark' } });
|
||||||
|
|
||||||
@@ -50,124 +53,6 @@ const RESULT_META = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function Avatar({ name, color, avatarUrl, bonusPoints = 0 }) {
|
|
||||||
const isRed = 'red' === color;
|
|
||||||
const initials = (name || '?').slice(0, 2).toUpperCase();
|
|
||||||
|
|
||||||
const gradient = isRed
|
|
||||||
? 'linear-gradient(135deg, rgba(173,10,5,0.6) 0%, rgba(246,125,82,0.4) 100%)'
|
|
||||||
: 'linear-gradient(135deg, rgba(35,111,135,0.6) 0%, rgba(41,128,185,0.4) 100%)';
|
|
||||||
const glow = isRed
|
|
||||||
? '0 0 0 3px rgba(173,10,5,0.2), 0 0 28px rgba(173,10,5,0.35)'
|
|
||||||
: '0 0 0 3px rgba(35,111,135,0.2), 0 0 28px rgba(35,111,135,0.35)';
|
|
||||||
const border = isRed
|
|
||||||
? 'rgba(173,10,5,0.5)'
|
|
||||||
: 'rgba(35,111,135,0.5)';
|
|
||||||
const textColor = isRed ? '#f67d52' : '#95cff5';
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 10, position: 'relative' }}>
|
|
||||||
<div style={{ position: 'relative' }}>
|
|
||||||
<div style={{
|
|
||||||
width: 72, height: 72, borderRadius: '50%',
|
|
||||||
background: avatarUrl ? 'transparent' : gradient,
|
|
||||||
border: `2px solid ${border}`,
|
|
||||||
boxShadow: glow,
|
|
||||||
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
|
||||||
font: '800 24px \'Rajdhani\', sans-serif',
|
|
||||||
color: textColor,
|
|
||||||
letterSpacing: 2,
|
|
||||||
overflow: 'hidden',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{avatarUrl ? (
|
|
||||||
<img
|
|
||||||
src={avatarUrl}
|
|
||||||
alt={name}
|
|
||||||
style={{
|
|
||||||
width: '100%',
|
|
||||||
height: '100%',
|
|
||||||
objectFit: 'cover',
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
initials
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
{0 < bonusPoints && (
|
|
||||||
<div style={{
|
|
||||||
position: 'absolute',
|
|
||||||
bottom: -6,
|
|
||||||
right: -6,
|
|
||||||
background: '#ffd700',
|
|
||||||
borderRadius: '50%',
|
|
||||||
width: 28,
|
|
||||||
height: 28,
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
boxShadow: '0 0 12px rgba(255, 215, 0, 0.6), 0 0 0 2px rgba(7, 9, 13, 1)',
|
|
||||||
border: '2px solid rgba(0,0,0,0.5)',
|
|
||||||
zIndex: 10,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<i className="fa fa-star" style={{ color: '#000', fontSize: 14 }} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<span style={{
|
|
||||||
font: '700 15px \'Rajdhani\', sans-serif',
|
|
||||||
color: textColor,
|
|
||||||
letterSpacing: 1,
|
|
||||||
maxWidth: 120, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
|
|
||||||
textAlign: 'center',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{name}
|
|
||||||
</span>
|
|
||||||
<span style={{
|
|
||||||
font: '600 10px \'Rajdhani\', sans-serif',
|
|
||||||
textTransform: 'uppercase',
|
|
||||||
letterSpacing: 2,
|
|
||||||
color: 'rgba(255,255,255,0.3)',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{isRed ? 'Red' : 'Blue'}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function StatRow({ icon, label, value, valueColor }) {
|
|
||||||
return (
|
|
||||||
<div style={{
|
|
||||||
display: 'flex', alignItems: 'center',
|
|
||||||
gap: 10, padding: '9px 0',
|
|
||||||
borderBottom: '1px solid rgba(255,255,255,0.05)',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<i className={`fa ${icon}`} style={{ width: 16, color: 'rgba(149,207,245,0.4)', fontSize: 13 }} />
|
|
||||||
<span style={{
|
|
||||||
font: '500 13px \'Rajdhani\', sans-serif',
|
|
||||||
color: 'rgba(255,255,255,0.45)',
|
|
||||||
flex: 1,
|
|
||||||
letterSpacing: 0.5,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{label}
|
|
||||||
</span>
|
|
||||||
<span style={{
|
|
||||||
font: '700 13px \'Rajdhani\', sans-serif',
|
|
||||||
color: valueColor || 'rgba(255,255,255,0.75)',
|
|
||||||
letterSpacing: 0.5,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{value}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function BattleDialog({ games }) {
|
export default function BattleDialog({ games }) {
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
const [game, setGame] = useState(null);
|
const [game, setGame] = useState(null);
|
||||||
@@ -250,7 +135,10 @@ export default function BattleDialog({ games }) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="bd-vs-panel">
|
<div className="bd-vs-panel">
|
||||||
<Avatar name={game.redName} color="red" avatarUrl={game.redAvatar} bonusPoints={game.redBonusPoints > game.blueBonusPoints ? game.redBonusPoints : 0} />
|
<Avatar
|
||||||
|
name={game.redName} color="red" avatarUrl={game.redAvatar}
|
||||||
|
bonusPoints={game.redBonusPoints > game.blueBonusPoints ? game.redBonusPoints : 0}
|
||||||
|
/>
|
||||||
<div className="bd-vs-center">
|
<div className="bd-vs-center">
|
||||||
<div className="bd-vs-score">
|
<div className="bd-vs-score">
|
||||||
<span className="bd-vs-score__red">{game.redPoints ?? '—'}</span>
|
<span className="bd-vs-score__red">{game.redPoints ?? '—'}</span>
|
||||||
@@ -258,11 +146,25 @@ export default function BattleDialog({ games }) {
|
|||||||
<span className="bd-vs-score__blue">{game.bluePoints ?? '—'}</span>
|
<span className="bd-vs-score__blue">{game.bluePoints ?? '—'}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="bd-vs-score" style={{ marginBottom: 8 }}>
|
<div className="bd-vs-score" style={{ marginBottom: 8 }}>
|
||||||
<span style={{ font: '700 13px \'Rajdhani\', sans-serif', color: '#f67d52', display: 'flex', alignItems: 'center', gap: 4 }}>
|
<span style={{
|
||||||
|
font: '700 13px \'Rajdhani\', sans-serif',
|
||||||
|
color: '#f67d52',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
gap: 4,
|
||||||
|
}}
|
||||||
|
>
|
||||||
<i className="fa fa-star" style={{ fontSize: 11 }} /> {(game.redBonusPoints ?? 0).toFixed(1)}
|
<i className="fa fa-star" style={{ fontSize: 11 }} /> {(game.redBonusPoints ?? 0).toFixed(1)}
|
||||||
</span>
|
</span>
|
||||||
<span className="bd-vs-score__sep">:</span>
|
<span className="bd-vs-score__sep">:</span>
|
||||||
<span style={{ font: '700 13px \'Rajdhani\', sans-serif', color: '#95cff5', display: 'flex', alignItems: 'center', gap: 4 }}>
|
<span style={{
|
||||||
|
font: '700 13px \'Rajdhani\', sans-serif',
|
||||||
|
color: '#95cff5',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
gap: 4,
|
||||||
|
}}
|
||||||
|
>
|
||||||
{(game.blueBonusPoints ?? 0).toFixed(1)} <i className="fa fa-star" style={{ fontSize: 11 }} />
|
{(game.blueBonusPoints ?? 0).toFixed(1)} <i className="fa fa-star" style={{ fontSize: 11 }} />
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -274,7 +176,10 @@ export default function BattleDialog({ games }) {
|
|||||||
<i className={`fa ${meta.icon}`} /> {meta.label}
|
<i className={`fa ${meta.icon}`} /> {meta.label}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Avatar name={game.blueName} color="blue" avatarUrl={game.blueAvatar} bonusPoints={game.blueBonusPoints > game.redBonusPoints ? game.blueBonusPoints : 0} />
|
<Avatar
|
||||||
|
name={game.blueName} color="blue" avatarUrl={game.blueAvatar}
|
||||||
|
bonusPoints={game.blueBonusPoints > game.redBonusPoints ? game.blueBonusPoints : 0}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="bd-stats">
|
<div className="bd-stats">
|
||||||
<StatRow icon="fa-calendar" label="Date" value={game.date ?? '—'} />
|
<StatRow icon="fa-calendar" label="Date" value={game.date ?? '—'} />
|
||||||
@@ -286,7 +191,10 @@ export default function BattleDialog({ games }) {
|
|||||||
)}
|
)}
|
||||||
<StatRow icon="fa-flag-checkered" label="End reason" value={endReason} />
|
<StatRow icon="fa-flag-checkered" label="End reason" value={endReason} />
|
||||||
{0 < pointDiff && (
|
{0 < pointDiff && (
|
||||||
<StatRow icon="fa-balance-scale" label="Winning margin" value={`${pointDiff} mine${1 === pointDiff ? '' : 's'}`} valueColor={winnerColor} />
|
<StatRow
|
||||||
|
icon="fa-balance-scale" label="Winning margin"
|
||||||
|
value={`${pointDiff} mine${1 === pointDiff ? '' : 's'}`} valueColor={winnerColor}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
<StatRow
|
<StatRow
|
||||||
icon="fa-bomb" label="Red used bomb"
|
icon="fa-bomb" label="Red used bomb"
|
||||||
@@ -299,62 +207,9 @@ export default function BattleDialog({ games }) {
|
|||||||
valueColor={game.blueExplodedBomb ? '#95cff5' : 'rgba(255,255,255,0.45)'}
|
valueColor={game.blueExplodedBomb ? '#95cff5' : 'rgba(255,255,255,0.45)'}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<BonusPoints
|
||||||
{(0 < game.redBonusPoints
|
game={game}
|
||||||
|| 0 < game.blueBonusPoints
|
/>
|
||||||
|| game.redBonusStats?.blindHits
|
|
||||||
|| game.blueBonusStats?.blindHits
|
|
||||||
) && (
|
|
||||||
<div style={{ padding: '16px 20px 0', borderTop: '1px solid rgba(255,255,255,0.08)', marginTop: 16, marginBottom: 16 }}>
|
|
||||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 }}>
|
|
||||||
{/* Red Bonus */}
|
|
||||||
<div style={{
|
|
||||||
padding: 16,
|
|
||||||
border: '1px solid rgba(173,10,5,0.2)',
|
|
||||||
borderRadius: 6,
|
|
||||||
background: 'rgba(173,10,5,0.05)',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span style={{ font: '700 12px \'Rajdhani\', sans-serif', textTransform: 'uppercase', letterSpacing: 2, color: '#ffd700', display: 'block', marginBottom: 12 }}>
|
|
||||||
<i className="fa fa-star" style={{ marginRight: 8 }} /> Red Bonus Statistics
|
|
||||||
</span>
|
|
||||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 0 }}>
|
|
||||||
<StatRow icon="fa-star" label="Total Bonus Points" value={(game.redBonusPoints ?? 0).toFixed(1)} valueColor="#ffd700" />
|
|
||||||
{0 < game.redBonusStats?.blindHits && <StatRow icon="fa-bullseye" label="Blind hits" value={game.redBonusStats.blindHits} />}
|
|
||||||
{0 < game.redBonusStats?.chainBest && <StatRow icon="fa-link" label="Best chain" value={game.redBonusStats.chainBest} />}
|
|
||||||
{0 < game.redBonusStats?.edgeMines && <StatRow icon="fa-border-all" label="Edge mines" value={game.redBonusStats.edgeMines} />}
|
|
||||||
{0 < game.redBonusStats?.lastMineHits && <StatRow icon="fa-hourglass-end" label="Endgame mines" value={game.redBonusStats.lastMineHits} />}
|
|
||||||
{0 < game.redBonusStats?.biggestReveal && <StatRow icon="fa-expand" label="Biggest reveal" value={game.redBonusStats.biggestReveal} />}
|
|
||||||
{!game.redBonusStats?.blindHits && !game.redBonusStats?.chainBest && !game.redBonusStats?.edgeMines && !game.redBonusStats?.lastMineHits && !game.redBonusStats?.biggestReveal
|
|
||||||
&& <StatRow icon="fa-minus-circle" label="Status" value="No bonuses" valueColor="rgba(255,255,255,0.3)" />}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Blue Bonus */}
|
|
||||||
<div style={{
|
|
||||||
padding: 16,
|
|
||||||
border: '1px solid rgba(149,207,245,0.2)',
|
|
||||||
borderRadius: 6,
|
|
||||||
background: 'rgba(149,207,245,0.05)',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span style={{ font: '700 12px \'Rajdhani\', sans-serif', textTransform: 'uppercase', letterSpacing: 2, color: '#ffd700', display: 'block', marginBottom: 12 }}>
|
|
||||||
<i className="fa fa-star" style={{ marginRight: 8 }} /> Blue Bonus Statistics
|
|
||||||
</span>
|
|
||||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 0 }}>
|
|
||||||
<StatRow icon="fa-star" label="Total Bonus Points" value={(game.blueBonusPoints ?? 0).toFixed(1)} valueColor="#ffd700" />
|
|
||||||
{0 < game.blueBonusStats?.blindHits && <StatRow icon="fa-bullseye" label="Blind hits" value={game.blueBonusStats.blindHits} />}
|
|
||||||
{0 < game.blueBonusStats?.chainBest && <StatRow icon="fa-link" label="Best chain" value={game.blueBonusStats.chainBest} />}
|
|
||||||
{0 < game.blueBonusStats?.edgeMines && <StatRow icon="fa-border-all" label="Edge mines" value={game.blueBonusStats.edgeMines} />}
|
|
||||||
{0 < game.blueBonusStats?.lastMineHits && <StatRow icon="fa-hourglass-end" label="Endgame mines" value={game.blueBonusStats.lastMineHits} />}
|
|
||||||
{0 < game.blueBonusStats?.biggestReveal && <StatRow icon="fa-expand" label="Biggest reveal" value={game.blueBonusStats.biggestReveal} />}
|
|
||||||
{!game.blueBonusStats?.blindHits && !game.blueBonusStats?.chainBest && !game.blueBonusStats?.edgeMines && !game.blueBonusStats?.lastMineHits && !game.blueBonusStats?.biggestReveal
|
|
||||||
&& <StatRow icon="fa-minus-circle" label="Status" value="No bonuses" valueColor="rgba(255,255,255,0.3)" />}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
|
|||||||
98
assets/js/components/battle-dialog/Avatar.jsx
Normal file
98
assets/js/components/battle-dialog/Avatar.jsx
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
/**
|
||||||
|
* This file is part of the SplendidBear Websites' projects.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2026 @ www.splendidbear.org
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
export default function Avatar({ name, color, avatarUrl, bonusPoints = 0 }) {
|
||||||
|
const isRed = 'red' === color;
|
||||||
|
const initials = (name || '?').slice(0, 2).toUpperCase();
|
||||||
|
|
||||||
|
const gradient = isRed
|
||||||
|
? 'linear-gradient(135deg, rgba(173,10,5,0.6) 0%, rgba(246,125,82,0.4) 100%)'
|
||||||
|
: 'linear-gradient(135deg, rgba(35,111,135,0.6) 0%, rgba(41,128,185,0.4) 100%)';
|
||||||
|
const glow = isRed
|
||||||
|
? '0 0 0 3px rgba(173,10,5,0.2), 0 0 28px rgba(173,10,5,0.35)'
|
||||||
|
: '0 0 0 3px rgba(35,111,135,0.2), 0 0 28px rgba(35,111,135,0.35)';
|
||||||
|
const border = isRed
|
||||||
|
? 'rgba(173,10,5,0.5)'
|
||||||
|
: 'rgba(35,111,135,0.5)';
|
||||||
|
const textColor = isRed ? '#f67d52' : '#95cff5';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 10, position: 'relative' }}>
|
||||||
|
<div style={{ position: 'relative' }}>
|
||||||
|
<div style={{
|
||||||
|
width: 72, height: 72, borderRadius: '50%',
|
||||||
|
background: avatarUrl ? 'transparent' : gradient,
|
||||||
|
border: `2px solid ${border}`,
|
||||||
|
boxShadow: glow,
|
||||||
|
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||||||
|
font: '800 24px \'Rajdhani\', sans-serif',
|
||||||
|
color: textColor,
|
||||||
|
letterSpacing: 2,
|
||||||
|
overflow: 'hidden',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{avatarUrl ? (
|
||||||
|
<img
|
||||||
|
src={avatarUrl}
|
||||||
|
alt={name}
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
objectFit: 'cover',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
initials
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{0 < bonusPoints && (
|
||||||
|
<div style={{
|
||||||
|
position: 'absolute',
|
||||||
|
bottom: -6,
|
||||||
|
right: -6,
|
||||||
|
background: '#ffd700',
|
||||||
|
borderRadius: '50%',
|
||||||
|
width: 28,
|
||||||
|
height: 28,
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
boxShadow: '0 0 12px rgba(255, 215, 0, 0.6), 0 0 0 2px rgba(7, 9, 13, 1)',
|
||||||
|
border: '2px solid rgba(0,0,0,0.5)',
|
||||||
|
zIndex: 10,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<i className="fa fa-star" style={{ color: '#000', fontSize: 14 }} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<span style={{
|
||||||
|
font: '700 15px \'Rajdhani\', sans-serif',
|
||||||
|
color: textColor,
|
||||||
|
letterSpacing: 1,
|
||||||
|
maxWidth: 120, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
|
||||||
|
textAlign: 'center',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{name}
|
||||||
|
</span>
|
||||||
|
<span style={{
|
||||||
|
font: '600 10px \'Rajdhani\', sans-serif',
|
||||||
|
textTransform: 'uppercase',
|
||||||
|
letterSpacing: 2,
|
||||||
|
color: 'rgba(255,255,255,0.3)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{isRed ? 'Red' : 'Blue'}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
139
assets/js/components/battle-dialog/BonusPoints.jsx
Normal file
139
assets/js/components/battle-dialog/BonusPoints.jsx
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
import { useMemo } from 'react';
|
||||||
|
import StatRow from './StatRow';
|
||||||
|
|
||||||
|
export default function BonusPoints({ game }) {
|
||||||
|
const hasBonuspoints = useMemo(
|
||||||
|
() => 0 < game?.redBonusPoints
|
||||||
|
|| 0 < game?.blueBonusPoints
|
||||||
|
|| game?.redBonusStats?.blindHits
|
||||||
|
|| game?.blueBonusStats?.blindHits,
|
||||||
|
[
|
||||||
|
game?.blueBonusPoints,
|
||||||
|
game?.blueBonusStats?.blindHits,
|
||||||
|
game?.redBonusPoints,
|
||||||
|
game?.redBonusStats?.blindHits,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
const hasRedNoBonuses = useMemo(
|
||||||
|
() => !game.redBonusStats?.blindHits
|
||||||
|
&& !game.redBonusStats?.chainBest
|
||||||
|
&& !game.redBonusStats?.edgeMines
|
||||||
|
&& !game.redBonusStats?.lastMineHits
|
||||||
|
&& !game.redBonusStats?.biggestReveal,
|
||||||
|
[
|
||||||
|
game.redBonusStats?.biggestReveal,
|
||||||
|
game.redBonusStats?.blindHits,
|
||||||
|
game.redBonusStats?.chainBest,
|
||||||
|
game.redBonusStats?.edgeMines,
|
||||||
|
game.redBonusStats?.lastMineHits,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
const hasBlueNoBonuses = useMemo(
|
||||||
|
() => !game.blueBonusStats?.blindHits
|
||||||
|
&& !game.blueBonusStats?.chainBest
|
||||||
|
&& !game.blueBonusStats?.edgeMines
|
||||||
|
&& !game.blueBonusStats?.lastMineHits
|
||||||
|
&& !game.blueBonusStats?.biggestReveal,
|
||||||
|
[
|
||||||
|
game.blueBonusStats?.biggestReveal,
|
||||||
|
game.blueBonusStats?.blindHits,
|
||||||
|
game.blueBonusStats?.chainBest,
|
||||||
|
game.blueBonusStats?.edgeMines,
|
||||||
|
game.blueBonusStats?.lastMineHits,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!hasBonuspoints) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{
|
||||||
|
padding: '16px 20px 0',
|
||||||
|
borderTop: '1px solid rgba(255,255,255,0.08)',
|
||||||
|
marginTop: 16,
|
||||||
|
marginBottom: 16,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 }}>
|
||||||
|
{/* Red Bonus */}
|
||||||
|
<div style={{
|
||||||
|
padding: 16,
|
||||||
|
border: '1px solid rgba(173,10,5,0.2)',
|
||||||
|
borderRadius: 6,
|
||||||
|
background: 'rgba(173,10,5,0.05)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span style={{
|
||||||
|
font: '700 12px \'Rajdhani\', sans-serif',
|
||||||
|
textTransform: 'uppercase',
|
||||||
|
letterSpacing: 2,
|
||||||
|
color: '#ffd700',
|
||||||
|
display: 'block',
|
||||||
|
marginBottom: 12,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<i className="fa fa-star" style={{ marginRight: 8 }} /> Red Bonus Statistics
|
||||||
|
</span>
|
||||||
|
<div style={{ display: 'flex', flexDirection: 'column', gap: 0 }}>
|
||||||
|
<StatRow
|
||||||
|
icon="fa-star" label="Total Bonus Points" value={(game.redBonusPoints ?? 0).toFixed(1)}
|
||||||
|
valueColor="#ffd700"
|
||||||
|
/>
|
||||||
|
{0 < game.redBonusStats?.blindHits
|
||||||
|
&& <StatRow icon="fa-bullseye" label="Blind hits" value={game.redBonusStats.blindHits} />}
|
||||||
|
{0 < game.redBonusStats?.chainBest
|
||||||
|
&& <StatRow icon="fa-link" label="Best chain" value={game.redBonusStats.chainBest} />}
|
||||||
|
{0 < game.redBonusStats?.edgeMines
|
||||||
|
&& <StatRow icon="fa-border-all" label="Edge mines" value={game.redBonusStats.edgeMines} />}
|
||||||
|
{0 < game.redBonusStats?.lastMineHits
|
||||||
|
&& <StatRow icon="fa-hourglass-end" label="Endgame mines" value={game.redBonusStats.lastMineHits} />}
|
||||||
|
{0 < game.redBonusStats?.biggestReveal
|
||||||
|
&& <StatRow icon="fa-expand" label="Biggest reveal" value={game.redBonusStats.biggestReveal} />}
|
||||||
|
{hasRedNoBonuses
|
||||||
|
&& <StatRow icon="fa-minus-circle" label="Status" value="No bonuses" valueColor="rgba(255,255,255,0.3)" />}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style={{
|
||||||
|
padding: 16,
|
||||||
|
border: '1px solid rgba(149,207,245,0.2)',
|
||||||
|
borderRadius: 6,
|
||||||
|
background: 'rgba(149,207,245,0.05)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span style={{
|
||||||
|
font: '700 12px \'Rajdhani\', sans-serif',
|
||||||
|
textTransform: 'uppercase',
|
||||||
|
letterSpacing: 2,
|
||||||
|
color: '#ffd700',
|
||||||
|
display: 'block',
|
||||||
|
marginBottom: 12,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<i className="fa fa-star" style={{ marginRight: 8 }} /> Blue Bonus Statistics
|
||||||
|
</span>
|
||||||
|
<div style={{ display: 'flex', flexDirection: 'column', gap: 0 }}>
|
||||||
|
<StatRow
|
||||||
|
icon="fa-star" label="Total Bonus Points" value={(game.blueBonusPoints ?? 0).toFixed(1)}
|
||||||
|
valueColor="#ffd700"
|
||||||
|
/>
|
||||||
|
{0 < game.blueBonusStats?.blindHits
|
||||||
|
&& <StatRow icon="fa-bullseye" label="Blind hits" value={game.blueBonusStats.blindHits} />}
|
||||||
|
{0 < game.blueBonusStats?.chainBest
|
||||||
|
&& <StatRow icon="fa-link" label="Best chain" value={game.blueBonusStats.chainBest} />}
|
||||||
|
{0 < game.blueBonusStats?.edgeMines
|
||||||
|
&& <StatRow icon="fa-border-all" label="Edge mines" value={game.blueBonusStats.edgeMines} />}
|
||||||
|
{0 < game.blueBonusStats?.lastMineHits
|
||||||
|
&& <StatRow icon="fa-hourglass-end" label="Endgame mines" value={game.blueBonusStats.lastMineHits} />}
|
||||||
|
{0 < game.blueBonusStats?.biggestReveal
|
||||||
|
&& <StatRow icon="fa-expand" label="Biggest reveal" value={game.blueBonusStats.biggestReveal} />}
|
||||||
|
{hasBlueNoBonuses
|
||||||
|
&& <StatRow icon="fa-minus-circle" label="Status" value="No bonuses" valueColor="rgba(255,255,255,0.3)" />}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
40
assets/js/components/battle-dialog/StatRow.jsx
Normal file
40
assets/js/components/battle-dialog/StatRow.jsx
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* This file is part of the SplendidBear Websites' projects.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2026 @ www.splendidbear.org
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
export default function StatRow({ icon, label, value, valueColor }) {
|
||||||
|
return (
|
||||||
|
<div style={{
|
||||||
|
display: 'flex', alignItems: 'center',
|
||||||
|
gap: 10, padding: '9px 0',
|
||||||
|
borderBottom: '1px solid rgba(255,255,255,0.05)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<i className={`fa ${icon}`} style={{ width: 16, color: 'rgba(149,207,245,0.4)', fontSize: 13 }} />
|
||||||
|
<span style={{
|
||||||
|
font: '500 13px \'Rajdhani\', sans-serif',
|
||||||
|
color: 'rgba(255,255,255,0.45)',
|
||||||
|
flex: 1,
|
||||||
|
letterSpacing: 0.5,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{label}
|
||||||
|
</span>
|
||||||
|
<span style={{
|
||||||
|
font: '700 13px \'Rajdhani\', sans-serif',
|
||||||
|
color: valueColor || 'rgba(255,255,255,0.75)',
|
||||||
|
letterSpacing: 0.5,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{value}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user