Files
Randify.pro/src/components/generators/RpsGenerator.astro
T
emil 8f11c5af43 feat: add favorites panel to meal generator, remove redundant Another one button
- Add clickable favorites counter with expandable panel
- Render saved recipes list with remove button
- Remove duplicate 'Another one' button (Generate already covers it)
- Sync favorite button state when removing from panel
2026-05-13 00:25:09 +03:00

146 lines
6.5 KiB
Plaintext

---
import { useT } from "../../i18n/translations";
const isRu = Astro.url.pathname.startsWith("/ru");
const T = useT(isRu ? "ru" : "en");
---
<div id="rps-generator" class="mt-8" data-ru={isRu ? "1" : "0"}>
<div class="rounded-xl bg-zinc-900/50 border border-zinc-800/60 p-5">
<p class="text-sm font-medium text-zinc-400 mb-3 text-center">
{isRu ? "Выберите ваш вариант:" : "Pick your move:"}
</p>
<div class="flex justify-center gap-3">
<button
id="rps-rock"
type="button"
data-move="rock"
class="rps-choice flex-1 sm:flex-none px-4 py-3 rounded-xl bg-zinc-800 border border-zinc-700 text-zinc-100 font-medium hover:bg-zinc-700 hover:border-zinc-600 active:bg-zinc-600 focus:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-zinc-950 transition-colors duration-100 cursor-pointer flex flex-col items-center gap-1"
>
<span class="text-2xl" aria-hidden="true">✊</span>
<span class="text-sm">{isRu ? "Камень" : "Rock"}</span>
</button>
<button
id="rps-paper"
type="button"
data-move="paper"
class="rps-choice flex-1 sm:flex-none px-4 py-3 rounded-xl bg-zinc-800 border border-zinc-700 text-zinc-100 font-medium hover:bg-zinc-700 hover:border-zinc-600 active:bg-zinc-600 focus:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-zinc-950 transition-colors duration-100 cursor-pointer flex flex-col items-center gap-1"
>
<span class="text-2xl" aria-hidden="true">✋</span>
<span class="text-sm">{isRu ? "Бумага" : "Paper"}</span>
</button>
<button
id="rps-scissors"
type="button"
data-move="scissors"
class="rps-choice flex-1 sm:flex-none px-4 py-3 rounded-xl bg-zinc-800 border border-zinc-700 text-zinc-100 font-medium hover:bg-zinc-700 hover:border-zinc-600 active:bg-zinc-600 focus:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-zinc-950 transition-colors duration-100 cursor-pointer flex flex-col items-center gap-1"
>
<span class="text-2xl" aria-hidden="true">✌️</span>
<span class="text-sm">{isRu ? "Ножницы" : "Scissors"}</span>
</button>
</div>
</div>
<div class="my-6 rounded-2xl bg-zinc-900/80 border border-zinc-800/80 p-8 h-52 overflow-hidden">
<div id="rps-result-area" class="h-full flex flex-col items-center justify-center gap-3">
<p id="rps-placeholder" class="text-zinc-500 text-center">
{isRu ? "Выберите ход, чтобы начать игру" : "Pick a move to start the game"}
</p>
<div id="rps-game-result" class="hidden w-full flex flex-col items-center justify-center gap-4">
<div class="flex items-center gap-4 sm:gap-6">
<div class="flex flex-col items-center gap-1">
<span class="text-xs text-zinc-500">{isRu ? "Вы" : "You"}</span>
<span id="rps-player-move" class="text-4xl"></span>
<span id="rps-player-label" class="text-sm text-zinc-300"></span>
</div>
<span class="text-xl text-zinc-600 font-bold">VS</span>
<div class="flex flex-col items-center gap-1">
<span class="text-xs text-zinc-500">{isRu ? "Бот" : "Bot"}</span>
<span id="rps-bot-move" class="text-4xl"></span>
<span id="rps-bot-label" class="text-sm text-zinc-300"></span>
</div>
</div>
<p id="rps-outcome" class="text-2xl font-bold"></p>
</div>
</div>
</div>
</div>
<script>
const isRu = document.documentElement.lang === "ru";
const LABELS: Record<string, { name: string; emoji: string }> = isRu
? {
rock: { name: "Камень", emoji: "✊" },
paper: { name: "Бумага", emoji: "✋" },
scissors: { name: "Ножницы", emoji: "✌️" },
}
: {
rock: { name: "Rock", emoji: "✊" },
paper: { name: "Paper", emoji: "✋" },
scissors: { name: "Scissors", emoji: "✌️" },
};
const OUTCOMES = {
win: { text: isRu ? "Победа!" : "You win!", color: "text-emerald-400" },
lose: { text: isRu ? "Поражение" : "You lose", color: "text-red-400" },
draw: { text: isRu ? "Ничья" : "Draw", color: "text-yellow-400" },
};
const MOVES = ["rock", "paper", "scissors"] as const;
const choices = document.querySelectorAll<HTMLButtonElement>(".rps-choice");
const placeholder = document.getElementById("rps-placeholder") as HTMLParagraphElement;
const gameResult = document.getElementById("rps-game-result") as HTMLDivElement;
const playerMoveEl = document.getElementById("rps-player-move") as HTMLSpanElement;
const playerLabelEl = document.getElementById("rps-player-label") as HTMLSpanElement;
const botMoveEl = document.getElementById("rps-bot-move") as HTMLSpanElement;
const botLabelEl = document.getElementById("rps-bot-label") as HTMLSpanElement;
const outcomeEl = document.getElementById("rps-outcome") as HTMLParagraphElement;
function getWinner(player: string, bot: string): "win" | "lose" | "draw" {
if (player === bot) return "draw";
if (
(player === "rock" && bot === "scissors") ||
(player === "paper" && bot === "rock") ||
(player === "scissors" && bot === "paper")
) {
return "win";
}
return "lose";
}
function play(playerMove: string) {
const botMove = MOVES[Math.floor(Math.random() * MOVES.length)];
const result = getWinner(playerMove, botMove);
choices.forEach((btn) => {
btn.classList.remove("border-accent", "bg-zinc-700");
btn.classList.add("border-zinc-700", "bg-zinc-800");
if (btn.dataset.move === playerMove) {
btn.classList.remove("border-zinc-700", "bg-zinc-800");
btn.classList.add("border-accent", "bg-zinc-700");
}
});
playerMoveEl.textContent = LABELS[playerMove].emoji;
playerLabelEl.textContent = LABELS[playerMove].name;
botMoveEl.textContent = LABELS[botMove].emoji;
botLabelEl.textContent = LABELS[botMove].name;
const outcome = OUTCOMES[result];
outcomeEl.textContent = outcome.text;
outcomeEl.className = `text-2xl font-bold ${outcome.color}`;
placeholder.classList.add("hidden");
gameResult.classList.remove("hidden");
}
choices.forEach((btn) => {
btn.addEventListener("click", () => {
const move = btn.dataset.move;
if (move) play(move);
});
});
</script>