You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

155 lines
3.4 KiB
TypeScript

import { useState, type CSSProperties } from 'react';
import { useT, t } from '../i18n';
// ---- Types ----
interface WanderingNPCPopupProps {
npcName: string;
message: string;
cost: number;
heroGold: number;
onAccept: () => void;
onDecline: () => void;
}
// ---- Styles ----
const overlayStyle: CSSProperties = {
position: 'absolute',
inset: 0,
zIndex: 800,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
pointerEvents: 'auto',
};
const backdropStyle: CSSProperties = {
position: 'absolute',
inset: 0,
backgroundColor: 'rgba(0, 0, 0, 0.55)',
};
const cardStyle: CSSProperties = {
position: 'relative',
width: '85%',
maxWidth: 320,
backgroundColor: 'rgba(15, 15, 25, 0.96)',
border: '2px solid rgba(218, 165, 32, 0.4)',
borderRadius: 16,
padding: '20px 18px 16px',
textAlign: 'center',
animation: 'wander-npc-pop 0.3s ease-out',
};
const titleStyle: CSSProperties = {
fontSize: 16,
fontWeight: 700,
color: '#daa520',
marginBottom: 8,
};
const messageStyle: CSSProperties = {
fontSize: 13,
color: '#ccc',
lineHeight: 1.5,
marginBottom: 16,
};
const costStyle: CSSProperties = {
fontSize: 14,
fontWeight: 700,
color: '#ffd700',
marginBottom: 16,
};
const btnRow: CSSProperties = {
display: 'flex',
gap: 10,
justifyContent: 'center',
};
const btnBase: CSSProperties = {
flex: 1,
padding: '10px 0',
borderRadius: 10,
fontSize: 13,
fontWeight: 700,
border: 'none',
cursor: 'pointer',
transition: 'background-color 150ms ease',
};
// ---- Component ----
export function WanderingNPCPopup({
npcName,
message,
cost,
heroGold,
onAccept,
onDecline,
}: WanderingNPCPopupProps) {
const tr = useT();
const [pending, setPending] = useState(false);
const canAfford = heroGold >= cost;
const handleAccept = () => {
if (!canAfford || pending) return;
setPending(true);
onAccept();
};
return (
<>
<style>{`
@keyframes wander-npc-pop {
0% { opacity: 0; transform: scale(0.92); }
100% { opacity: 1; transform: scale(1); }
}
`}</style>
<div style={overlayStyle}>
<div style={backdropStyle} onClick={onDecline} />
<div style={cardStyle}>
<div style={titleStyle}>{npcName}</div>
<div style={messageStyle}>{message}</div>
<div style={costStyle}>
{t(tr.giveGoldForItem, { cost })}
</div>
{!canAfford && (
<div style={{ fontSize: 11, color: '#ff6666', marginBottom: 10 }}>
{tr.notEnoughGold} ({heroGold}/{cost})
</div>
)}
<div style={btnRow}>
<button
style={{
...btnBase,
backgroundColor: canAfford && !pending
? 'rgba(68, 200, 68, 0.25)'
: 'rgba(100, 100, 100, 0.15)',
color: canAfford && !pending ? '#88dd88' : '#666',
}}
onClick={handleAccept}
disabled={!canAfford || pending}
>
{pending ? tr.giving : tr.accept}
</button>
<button
style={{
...btnBase,
backgroundColor: 'rgba(200, 68, 68, 0.15)',
color: '#ff8888',
}}
onClick={onDecline}
disabled={pending}
>
{tr.decline}
</button>
</div>
</div>
</div>
</>
);
}