Compare commits
7 Commits
2.0.2
...
634d012097
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
634d012097 | ||
|
|
301d5b131c | ||
|
|
4c8b0cfed7 | ||
|
|
31ed600c97 | ||
|
|
d016868ff2 | ||
|
|
89300bc021 | ||
|
|
de502741e7 |
@@ -26,7 +26,7 @@
|
|||||||
.winner-announcement {
|
.winner-announcement {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin: 20px 0 0 0;
|
margin: 20px 0 0 0;
|
||||||
padding: 24px 16px;
|
padding: 32px 16px 24px 16px; /* extra top padding to keep icons inside */
|
||||||
background: linear-gradient(135deg, #ff9800 0%, #ffa726 100%);
|
background: linear-gradient(135deg, #ff9800 0%, #ffa726 100%);
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
@@ -35,13 +35,13 @@
|
|||||||
box-shadow: 0 8px 32px rgba(255, 152, 0, 0.3);
|
box-shadow: 0 8px 32px rgba(255, 152, 0, 0.3);
|
||||||
animation: celebrationPulse 2s ease-in-out infinite;
|
animation: celebrationPulse 2s ease-in-out infinite;
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: visible; /* avoid clipping decorative icons */
|
||||||
}
|
}
|
||||||
|
|
||||||
.winner-announcement::before {
|
.winner-announcement::before {
|
||||||
content: '🎉';
|
content: '🎉';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: -10px;
|
top: 6px;
|
||||||
left: 20px;
|
left: 20px;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
animation: bounce 1s ease-in-out infinite;
|
animation: bounce 1s ease-in-out infinite;
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
.winner-announcement::after {
|
.winner-announcement::after {
|
||||||
content: '🏆';
|
content: '🏆';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: -10px;
|
top: 6px;
|
||||||
right: 20px;
|
right: 20px;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
animation: bounce 1s ease-in-out infinite 0.5s;
|
animation: bounce 1s ease-in-out infinite 0.5s;
|
||||||
|
|||||||
@@ -76,7 +76,7 @@
|
|||||||
/* Game item with better symmetry and spacing */
|
/* Game item with better symmetry and spacing */
|
||||||
.game-item {
|
.game-item {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: auto 1fr auto;
|
grid-template-columns: 1fr auto;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: var(--space-md);
|
gap: var(--space-md);
|
||||||
padding: var(--space-lg);
|
padding: var(--space-lg);
|
||||||
|
|||||||
@@ -82,7 +82,9 @@ export default function GameList({
|
|||||||
<Card
|
<Card
|
||||||
key={game.id}
|
key={game.id}
|
||||||
variant="elevated"
|
variant="elevated"
|
||||||
className={game.status === 'completed' ? styles['completed'] : styles['active']}
|
className={
|
||||||
|
styles['game-item'] + ' ' + (game.status === 'completed' ? styles['completed'] : styles['active'])
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={styles['game-info']}
|
className={styles['game-info']}
|
||||||
|
|||||||
@@ -56,6 +56,17 @@ const Player1Step = ({ playerNameHistory, onNext, onCancel, initialValue = '' }:
|
|||||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
const inputRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const el = inputRef.current;
|
||||||
|
if (el) {
|
||||||
|
el.focus();
|
||||||
|
const end = el.value.length;
|
||||||
|
try {
|
||||||
|
el.setSelectionRange(end, end);
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!player1) {
|
if (!player1) {
|
||||||
setFilteredNames(playerNameHistory);
|
setFilteredNames(playerNameHistory);
|
||||||
@@ -296,6 +307,17 @@ const Player2Step = ({ playerNameHistory, onNext, onCancel, initialValue = '' }:
|
|||||||
const [filteredNames, setFilteredNames] = useState(playerNameHistory);
|
const [filteredNames, setFilteredNames] = useState(playerNameHistory);
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
const inputRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const el = inputRef.current;
|
||||||
|
if (el) {
|
||||||
|
el.focus();
|
||||||
|
const end = el.value.length;
|
||||||
|
try {
|
||||||
|
el.setSelectionRange(end, end);
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!player2) {
|
if (!player2) {
|
||||||
setFilteredNames(playerNameHistory);
|
setFilteredNames(playerNameHistory);
|
||||||
@@ -430,6 +452,17 @@ const Player3Step = ({ playerNameHistory, onNext, onCancel, initialValue = '' }:
|
|||||||
const [filteredNames, setFilteredNames] = useState(playerNameHistory);
|
const [filteredNames, setFilteredNames] = useState(playerNameHistory);
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
const inputRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const el = inputRef.current;
|
||||||
|
if (el) {
|
||||||
|
el.focus();
|
||||||
|
const end = el.value.length;
|
||||||
|
try {
|
||||||
|
el.setSelectionRange(end, end);
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!player3) {
|
if (!player3) {
|
||||||
setFilteredNames(playerNameHistory);
|
setFilteredNames(playerNameHistory);
|
||||||
@@ -579,6 +612,8 @@ const GameTypeStep = ({ onNext, onCancel, initialValue = '' }: GameTypeStepProps
|
|||||||
|
|
||||||
const handleSelect = (selectedType: string) => {
|
const handleSelect = (selectedType: string) => {
|
||||||
setGameType(selectedType);
|
setGameType(selectedType);
|
||||||
|
// Auto-advance to next step on selection
|
||||||
|
onNext(selectedType);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = (e: Event) => {
|
const handleSubmit = (e: Event) => {
|
||||||
@@ -673,7 +708,11 @@ const RaceToStep = ({ onNext, onCancel, initialValue = '', gameType }: RaceToSte
|
|||||||
|
|
||||||
const handleQuickPick = (value: number) => {
|
const handleQuickPick = (value: number) => {
|
||||||
// For endlos (endless) games, use Infinity to prevent automatic completion
|
// For endlos (endless) games, use Infinity to prevent automatic completion
|
||||||
setRaceTo(value === 0 ? 'Infinity' : value);
|
const selected = value === 0 ? 'Infinity' : value;
|
||||||
|
setRaceTo(selected);
|
||||||
|
// Auto-advance to the next step (finalize) when a quick pick is chosen
|
||||||
|
const raceToValue = selected === 'Infinity' ? Infinity : (parseInt(String(selected), 10) || 0);
|
||||||
|
onNext(raceToValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleInputChange = (e: Event) => {
|
const handleInputChange = (e: Event) => {
|
||||||
|
|||||||
@@ -161,7 +161,6 @@ input:focus, select:focus {
|
|||||||
transform: translateY(-1px);
|
transform: translateY(-1px);
|
||||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary:hover {
|
.btn-primary:hover {
|
||||||
background: var(--color-primary-hover);
|
background: var(--color-primary-hover);
|
||||||
@@ -267,11 +266,6 @@ input:focus, select:focus {
|
|||||||
border: 0;
|
border: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Focus styles for better accessibility */
|
|
||||||
*:focus {
|
|
||||||
outline: 2px solid var(--color-primary);
|
|
||||||
outline-offset: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Skip link for keyboard navigation */
|
/* Skip link for keyboard navigation */
|
||||||
.skip-link {
|
.skip-link {
|
||||||
|
|||||||
Reference in New Issue
Block a user