Fix Russian generator pages: use individual pages instead of dynamic route
The dynamic [slug].astro imported all 10 generator components, causing Astro to bundle all their scripts into every Russian page. Scripts then crashed trying to find DOM elements that don't exist on the page. Each Russian generator page now imports only its own component, matching the English page structure. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
65e42e7d44
commit
be6a0d712f
@@ -1,227 +0,0 @@
|
||||
---
|
||||
import { generators } from '../../../data/generators';
|
||||
import BaseLayout from '../../../layouts/BaseLayout.astro';
|
||||
import AdBanner from '../../../components/AdBanner.astro';
|
||||
import SeoBlock from '../../../components/SeoBlock.astro';
|
||||
|
||||
import NumberGenerator from '../../../components/generators/NumberGenerator.astro';
|
||||
import ColorGenerator from '../../../components/generators/ColorGenerator.astro';
|
||||
import PasswordGenerator from '../../../components/generators/PasswordGenerator.astro';
|
||||
import LotteryGenerator from '../../../components/generators/LotteryGenerator.astro';
|
||||
import DiceGenerator from '../../../components/generators/DiceGenerator.astro';
|
||||
import CardGenerator from '../../../components/generators/CardGenerator.astro';
|
||||
import CoinGenerator from '../../../components/generators/CoinGenerator.astro';
|
||||
import ListGenerator from '../../../components/generators/ListGenerator.astro';
|
||||
import UuidGenerator from '../../../components/generators/UuidGenerator.astro';
|
||||
import WheelSpinner from '../../../components/generators/WheelSpinner.astro';
|
||||
|
||||
export function getStaticPaths() {
|
||||
return generators.map((g) => ({
|
||||
params: { slug: g.slug },
|
||||
props: { generator: g },
|
||||
}));
|
||||
}
|
||||
|
||||
const { generator } = Astro.props;
|
||||
const { slug } = Astro.params;
|
||||
|
||||
const seoContent: Record<string, { howTo: string[]; whenTo: string[] }> = {
|
||||
numbers: {
|
||||
howTo: [
|
||||
'Введите минимальное значение в поле «От».',
|
||||
'Введите максимальное значение в поле «До».',
|
||||
'Нажмите «Сгенерировать» — случайное число появится мгновенно.',
|
||||
'Нажмите на число, чтобы скопировать его в буфер обмена.',
|
||||
],
|
||||
whenTo: [
|
||||
'Выбор победителя в розыгрыше или конкурсе.',
|
||||
'Определение случайного первого игрока в настольной игре.',
|
||||
'Быстрое принятие решения между пронумерованными вариантами.',
|
||||
'Генерация тестовых данных с числами в заданном диапазоне.',
|
||||
],
|
||||
},
|
||||
colors: {
|
||||
howTo: [
|
||||
'Нажмите «Сгенерировать», чтобы получить случайный цвет.',
|
||||
'Цвет отображается в форматах HEX, RGB и HSL одновременно.',
|
||||
'Нажмите на иконку копирования рядом с нужным форматом.',
|
||||
],
|
||||
whenTo: [
|
||||
'Поиск вдохновения для цветовой палитры.',
|
||||
'Случайный выбор цвета для дизайна или иллюстрации.',
|
||||
'Генерация тестовых данных с цветовыми значениями.',
|
||||
],
|
||||
},
|
||||
password: {
|
||||
howTo: [
|
||||
'Задайте длину пароля с помощью ползунка.',
|
||||
'Выберите типы символов: заглавные, строчные, цифры, спецсимволы.',
|
||||
'Нажмите «Сгенерировать» — готовый пароль появится на экране.',
|
||||
'Нажмите на пароль, чтобы скопировать его.',
|
||||
],
|
||||
whenTo: [
|
||||
'Создание надёжного пароля для нового аккаунта.',
|
||||
'Генерация секретного ключа или токена.',
|
||||
'Регулярное обновление паролей для повышения безопасности.',
|
||||
],
|
||||
},
|
||||
lottery: {
|
||||
howTo: [
|
||||
'Укажите диапазон чисел в полях «От» и «До».',
|
||||
'Задайте количество чисел для розыгрыша.',
|
||||
'Нажмите «Тянуть» — выпавшие числа появятся на экране.',
|
||||
'Нажмите «Копировать», чтобы сохранить результат.',
|
||||
],
|
||||
whenTo: [
|
||||
'Розыгрыш лотерейных номеров.',
|
||||
'Жеребьёвка участников конкурса.',
|
||||
'Случайный выбор нескольких уникальных чисел.',
|
||||
],
|
||||
},
|
||||
dice: {
|
||||
howTo: [
|
||||
'Укажите количество кубиков (до 20).',
|
||||
'Выберите количество граней: d4, d6, d8, d10, d12, d20 или d100.',
|
||||
'Нажмите «Бросить» — результаты отобразятся мгновенно.',
|
||||
'Нажмите «Копировать», чтобы сохранить результат.',
|
||||
],
|
||||
whenTo: [
|
||||
'Броски в настольных ролевых играх (D&D и другие).',
|
||||
'Генерация случайных чисел для настольных игр.',
|
||||
'Проверка вероятностей и симуляции.',
|
||||
],
|
||||
},
|
||||
cards: {
|
||||
howTo: [
|
||||
'Укажите количество карт для розыгрыша.',
|
||||
'Включите «Разрешить повторения», если нужны дубли.',
|
||||
'Нажмите «Тянуть» — карты появятся на экране.',
|
||||
'Нажмите «Копировать», чтобы скопировать результат.',
|
||||
],
|
||||
whenTo: [
|
||||
'Случайная раздача карт для карточных игр.',
|
||||
'Выбор случайных карт для гаданий.',
|
||||
'Генерация случайных комбинаций карт для тестирования.',
|
||||
],
|
||||
},
|
||||
coin: {
|
||||
howTo: [
|
||||
'Выберите количество монет с помощью ползунка.',
|
||||
'Нажмите «Подбросить» — орёл или решка.',
|
||||
'При нескольких монетах отображается итоговый счёт.',
|
||||
'Нажмите «Копировать», чтобы сохранить результат.',
|
||||
],
|
||||
whenTo: [
|
||||
'Принятие решений по принципу «орёл или решка».',
|
||||
'Определение очерёдности в игре.',
|
||||
'Симуляция случайных событий с равной вероятностью.',
|
||||
],
|
||||
},
|
||||
list: {
|
||||
howTo: [
|
||||
'Введите список элементов — по одному на строку.',
|
||||
'Укажите, сколько элементов выбрать.',
|
||||
'При необходимости разрешите повторения.',
|
||||
'Нажмите «Выбрать» — победители выделятся на экране.',
|
||||
],
|
||||
whenTo: [
|
||||
'Розыгрыш победителей конкурса.',
|
||||
'Случайное распределение задач между участниками команды.',
|
||||
'Выбор случайного варианта из списка.',
|
||||
],
|
||||
},
|
||||
uuid: {
|
||||
howTo: [
|
||||
'Выберите тип: UUID v4, Hex или Base64.',
|
||||
'Для Hex и Base64 задайте длину в байтах.',
|
||||
'Укажите количество токенов.',
|
||||
'Нажмите «Сгенерировать» и скопируйте результат.',
|
||||
],
|
||||
whenTo: [
|
||||
'Генерация уникальных идентификаторов для баз данных.',
|
||||
'Создание токенов для API и сессий.',
|
||||
'Генерация случайных ключей шифрования.',
|
||||
],
|
||||
},
|
||||
wheel: {
|
||||
howTo: [
|
||||
'Введите варианты в поле — по одному на строку (от 2 до 24).',
|
||||
'Колесо обновляется автоматически.',
|
||||
'Нажмите «Крутить» и дождитесь результата.',
|
||||
'Победитель выделяется — скопируйте его кнопкой «Копировать».',
|
||||
],
|
||||
whenTo: [
|
||||
'Случайный выбор победителя розыгрыша.',
|
||||
'Принятие решений в команде.',
|
||||
'Распределение ролей или задач между участниками.',
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const seo = seoContent[slug] ?? { howTo: [], whenTo: [] };
|
||||
---
|
||||
|
||||
<BaseLayout
|
||||
title={generator.ruSeoTitle}
|
||||
description={generator.ruSeoDescription}
|
||||
lang="ru"
|
||||
>
|
||||
<div class="max-w-2xl mx-auto px-4 py-12 sm:py-20">
|
||||
<nav aria-label="Breadcrumb" class="mb-10">
|
||||
<a
|
||||
href="/ru/"
|
||||
class="inline-flex items-center gap-1.5 text-sm text-zinc-500 hover:text-zinc-200 transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-[#534AB7] rounded"
|
||||
aria-label="Все генераторы"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="14"
|
||||
height="14"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2.5"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path d="m15 18-6-6 6-6"/>
|
||||
</svg>
|
||||
Все генераторы
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
<header class="mb-2">
|
||||
<div class="flex items-center gap-2 mb-4">
|
||||
<span
|
||||
class="inline-block w-2.5 h-2.5 rounded-full bg-[#534AB7]"
|
||||
aria-hidden="true"
|
||||
></span>
|
||||
<span class="text-sm font-medium text-zinc-400 uppercase tracking-widest">randify</span>
|
||||
</div>
|
||||
<h1 class="text-3xl sm:text-4xl font-bold text-zinc-100">
|
||||
Генератор {generator.ruTitle.toLowerCase()}
|
||||
</h1>
|
||||
<p class="mt-2 text-base text-zinc-400">{generator.ruDescription}</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
{slug === 'numbers' && <NumberGenerator />}
|
||||
{slug === 'colors' && <ColorGenerator />}
|
||||
{slug === 'password' && <PasswordGenerator />}
|
||||
{slug === 'lottery' && <LotteryGenerator />}
|
||||
{slug === 'dice' && <DiceGenerator />}
|
||||
{slug === 'cards' && <CardGenerator />}
|
||||
{slug === 'coin' && <CoinGenerator />}
|
||||
{slug === 'list' && <ListGenerator />}
|
||||
{slug === 'uuid' && <UuidGenerator />}
|
||||
{slug === 'wheel' && <WheelSpinner />}
|
||||
</main>
|
||||
|
||||
<div class="mt-12 flex justify-center">
|
||||
<AdBanner size="tile" />
|
||||
</div>
|
||||
|
||||
<SeoBlock howTo={seo.howTo} whenTo={seo.whenTo} lang="ru" />
|
||||
</div>
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
import BaseLayout from '../../../layouts/BaseLayout.astro';
|
||||
import CardGenerator from '../../../components/generators/CardGenerator.astro';
|
||||
import AdBanner from '../../../components/AdBanner.astro';
|
||||
import SeoBlock from '../../../components/SeoBlock.astro';
|
||||
import { generators } from '../../../data/generators';
|
||||
|
||||
const generator = generators.find((g) => g.slug === 'cards')!;
|
||||
---
|
||||
|
||||
<BaseLayout title={generator.ruSeoTitle} description={generator.ruSeoDescription} lang="ru">
|
||||
<div class="max-w-2xl mx-auto px-4 py-12 sm:py-20">
|
||||
<nav aria-label="Breadcrumb" class="mb-10">
|
||||
<a href="/ru/" class="inline-flex items-center gap-1.5 text-sm text-zinc-500 hover:text-zinc-200 transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-[#534AB7] rounded" aria-label="Все генераторы">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m15 18-6-6 6-6"/></svg>
|
||||
Все генераторы
|
||||
</a>
|
||||
</nav>
|
||||
<header class="mb-2">
|
||||
<div class="flex items-center gap-2 mb-4">
|
||||
<span class="inline-block w-2.5 h-2.5 rounded-full bg-[#534AB7]" aria-hidden="true"></span>
|
||||
<span class="text-sm font-medium text-zinc-400 uppercase tracking-widest">randify</span>
|
||||
</div>
|
||||
<h1 class="text-3xl sm:text-4xl font-bold text-zinc-100">Генератор карт</h1>
|
||||
<p class="mt-2 text-base text-zinc-400">{generator.ruDescription}</p>
|
||||
</header>
|
||||
<main><CardGenerator /></main>
|
||||
<div class="mt-12 flex justify-center"><AdBanner size="tile" /></div>
|
||||
<SeoBlock lang="ru" howTo={[
|
||||
'Укажите количество карт для розыгрыша.',
|
||||
'Включите «Разрешить повторения», если нужны дубли.',
|
||||
'Нажмите «Тянуть» — карты появятся на экране.',
|
||||
'Нажмите «Копировать», чтобы скопировать результат.',
|
||||
]} whenTo={[
|
||||
'Случайная раздача карт для карточных игр.',
|
||||
'Выбор случайных карт для гаданий.',
|
||||
'Генерация случайных комбинаций карт для тестирования.',
|
||||
]} />
|
||||
</div>
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
import BaseLayout from '../../../layouts/BaseLayout.astro';
|
||||
import CoinGenerator from '../../../components/generators/CoinGenerator.astro';
|
||||
import AdBanner from '../../../components/AdBanner.astro';
|
||||
import SeoBlock from '../../../components/SeoBlock.astro';
|
||||
import { generators } from '../../../data/generators';
|
||||
|
||||
const generator = generators.find((g) => g.slug === 'coin')!;
|
||||
---
|
||||
|
||||
<BaseLayout title={generator.ruSeoTitle} description={generator.ruSeoDescription} lang="ru">
|
||||
<div class="max-w-2xl mx-auto px-4 py-12 sm:py-20">
|
||||
<nav aria-label="Breadcrumb" class="mb-10">
|
||||
<a href="/ru/" class="inline-flex items-center gap-1.5 text-sm text-zinc-500 hover:text-zinc-200 transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-[#534AB7] rounded" aria-label="Все генераторы">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m15 18-6-6 6-6"/></svg>
|
||||
Все генераторы
|
||||
</a>
|
||||
</nav>
|
||||
<header class="mb-2">
|
||||
<div class="flex items-center gap-2 mb-4">
|
||||
<span class="inline-block w-2.5 h-2.5 rounded-full bg-[#534AB7]" aria-hidden="true"></span>
|
||||
<span class="text-sm font-medium text-zinc-400 uppercase tracking-widest">randify</span>
|
||||
</div>
|
||||
<h1 class="text-3xl sm:text-4xl font-bold text-zinc-100">Подбросить монетку</h1>
|
||||
<p class="mt-2 text-base text-zinc-400">{generator.ruDescription}</p>
|
||||
</header>
|
||||
<main><CoinGenerator /></main>
|
||||
<div class="mt-12 flex justify-center"><AdBanner size="tile" /></div>
|
||||
<SeoBlock lang="ru" howTo={[
|
||||
'Выберите количество монет с помощью ползунка.',
|
||||
'Нажмите «Подбросить» — орёл или решка.',
|
||||
'При нескольких монетах отображается итоговый счёт.',
|
||||
'Нажмите «Копировать», чтобы сохранить результат.',
|
||||
]} whenTo={[
|
||||
'Принятие решений по принципу «орёл или решка».',
|
||||
'Определение очерёдности в игре.',
|
||||
'Симуляция случайных событий с равной вероятностью.',
|
||||
]} />
|
||||
</div>
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
import BaseLayout from '../../../layouts/BaseLayout.astro';
|
||||
import ColorGenerator from '../../../components/generators/ColorGenerator.astro';
|
||||
import AdBanner from '../../../components/AdBanner.astro';
|
||||
import SeoBlock from '../../../components/SeoBlock.astro';
|
||||
import { generators } from '../../../data/generators';
|
||||
|
||||
const generator = generators.find((g) => g.slug === 'colors')!;
|
||||
---
|
||||
|
||||
<BaseLayout title={generator.ruSeoTitle} description={generator.ruSeoDescription} lang="ru">
|
||||
<div class="max-w-2xl mx-auto px-4 py-12 sm:py-20">
|
||||
<nav aria-label="Breadcrumb" class="mb-10">
|
||||
<a href="/ru/" class="inline-flex items-center gap-1.5 text-sm text-zinc-500 hover:text-zinc-200 transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-[#534AB7] rounded" aria-label="Все генераторы">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m15 18-6-6 6-6"/></svg>
|
||||
Все генераторы
|
||||
</a>
|
||||
</nav>
|
||||
<header class="mb-2">
|
||||
<div class="flex items-center gap-2 mb-4">
|
||||
<span class="inline-block w-2.5 h-2.5 rounded-full bg-[#534AB7]" aria-hidden="true"></span>
|
||||
<span class="text-sm font-medium text-zinc-400 uppercase tracking-widest">randify</span>
|
||||
</div>
|
||||
<h1 class="text-3xl sm:text-4xl font-bold text-zinc-100">Генератор цветов</h1>
|
||||
<p class="mt-2 text-base text-zinc-400">{generator.ruDescription}</p>
|
||||
</header>
|
||||
<main><ColorGenerator /></main>
|
||||
<div class="mt-12 flex justify-center"><AdBanner size="tile" /></div>
|
||||
<SeoBlock lang="ru" howTo={[
|
||||
'Нажмите «Сгенерировать», чтобы получить случайный цвет.',
|
||||
'Цвет отображается в форматах HEX, RGB и HSL одновременно.',
|
||||
'Нажмите на иконку копирования рядом с нужным форматом.',
|
||||
]} whenTo={[
|
||||
'Поиск вдохновения для цветовой палитры.',
|
||||
'Случайный выбор цвета для дизайна или иллюстрации.',
|
||||
'Генерация тестовых данных с цветовыми значениями.',
|
||||
]} />
|
||||
</div>
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
import BaseLayout from '../../../layouts/BaseLayout.astro';
|
||||
import DiceGenerator from '../../../components/generators/DiceGenerator.astro';
|
||||
import AdBanner from '../../../components/AdBanner.astro';
|
||||
import SeoBlock from '../../../components/SeoBlock.astro';
|
||||
import { generators } from '../../../data/generators';
|
||||
|
||||
const generator = generators.find((g) => g.slug === 'dice')!;
|
||||
---
|
||||
|
||||
<BaseLayout title={generator.ruSeoTitle} description={generator.ruSeoDescription} lang="ru">
|
||||
<div class="max-w-2xl mx-auto px-4 py-12 sm:py-20">
|
||||
<nav aria-label="Breadcrumb" class="mb-10">
|
||||
<a href="/ru/" class="inline-flex items-center gap-1.5 text-sm text-zinc-500 hover:text-zinc-200 transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-[#534AB7] rounded" aria-label="Все генераторы">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m15 18-6-6 6-6"/></svg>
|
||||
Все генераторы
|
||||
</a>
|
||||
</nav>
|
||||
<header class="mb-2">
|
||||
<div class="flex items-center gap-2 mb-4">
|
||||
<span class="inline-block w-2.5 h-2.5 rounded-full bg-[#534AB7]" aria-hidden="true"></span>
|
||||
<span class="text-sm font-medium text-zinc-400 uppercase tracking-widest">randify</span>
|
||||
</div>
|
||||
<h1 class="text-3xl sm:text-4xl font-bold text-zinc-100">Бросить кубик онлайн</h1>
|
||||
<p class="mt-2 text-base text-zinc-400">{generator.ruDescription}</p>
|
||||
</header>
|
||||
<main><DiceGenerator /></main>
|
||||
<div class="mt-12 flex justify-center"><AdBanner size="tile" /></div>
|
||||
<SeoBlock lang="ru" howTo={[
|
||||
'Укажите количество кубиков (до 20).',
|
||||
'Выберите количество граней: d4, d6, d8, d10, d12, d20 или d100.',
|
||||
'Нажмите «Бросить» — результаты отобразятся мгновенно.',
|
||||
'Нажмите «Копировать», чтобы сохранить результат.',
|
||||
]} whenTo={[
|
||||
'Броски в настольных ролевых играх (D&D и другие).',
|
||||
'Генерация случайных чисел для настольных игр.',
|
||||
'Проверка вероятностей и симуляции.',
|
||||
]} />
|
||||
</div>
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
import BaseLayout from '../../../layouts/BaseLayout.astro';
|
||||
import ListGenerator from '../../../components/generators/ListGenerator.astro';
|
||||
import AdBanner from '../../../components/AdBanner.astro';
|
||||
import SeoBlock from '../../../components/SeoBlock.astro';
|
||||
import { generators } from '../../../data/generators';
|
||||
|
||||
const generator = generators.find((g) => g.slug === 'list')!;
|
||||
---
|
||||
|
||||
<BaseLayout title={generator.ruSeoTitle} description={generator.ruSeoDescription} lang="ru">
|
||||
<div class="max-w-2xl mx-auto px-4 py-12 sm:py-20">
|
||||
<nav aria-label="Breadcrumb" class="mb-10">
|
||||
<a href="/ru/" class="inline-flex items-center gap-1.5 text-sm text-zinc-500 hover:text-zinc-200 transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-[#534AB7] rounded" aria-label="Все генераторы">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m15 18-6-6 6-6"/></svg>
|
||||
Все генераторы
|
||||
</a>
|
||||
</nav>
|
||||
<header class="mb-2">
|
||||
<div class="flex items-center gap-2 mb-4">
|
||||
<span class="inline-block w-2.5 h-2.5 rounded-full bg-[#534AB7]" aria-hidden="true"></span>
|
||||
<span class="text-sm font-medium text-zinc-400 uppercase tracking-widest">randify</span>
|
||||
</div>
|
||||
<h1 class="text-3xl sm:text-4xl font-bold text-zinc-100">Случайный выбор из списка</h1>
|
||||
<p class="mt-2 text-base text-zinc-400">{generator.ruDescription}</p>
|
||||
</header>
|
||||
<main><ListGenerator /></main>
|
||||
<div class="mt-12 flex justify-center"><AdBanner size="tile" /></div>
|
||||
<SeoBlock lang="ru" howTo={[
|
||||
'Введите список элементов — по одному на строку.',
|
||||
'Укажите, сколько элементов выбрать.',
|
||||
'При необходимости разрешите повторения.',
|
||||
'Нажмите «Выбрать» — результаты появятся на экране.',
|
||||
]} whenTo={[
|
||||
'Розыгрыш победителей конкурса.',
|
||||
'Случайное распределение задач между участниками команды.',
|
||||
'Выбор случайного варианта из списка.',
|
||||
]} />
|
||||
</div>
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
import BaseLayout from '../../../layouts/BaseLayout.astro';
|
||||
import LotteryGenerator from '../../../components/generators/LotteryGenerator.astro';
|
||||
import AdBanner from '../../../components/AdBanner.astro';
|
||||
import SeoBlock from '../../../components/SeoBlock.astro';
|
||||
import { generators } from '../../../data/generators';
|
||||
|
||||
const generator = generators.find((g) => g.slug === 'lottery')!;
|
||||
---
|
||||
|
||||
<BaseLayout title={generator.ruSeoTitle} description={generator.ruSeoDescription} lang="ru">
|
||||
<div class="max-w-2xl mx-auto px-4 py-12 sm:py-20">
|
||||
<nav aria-label="Breadcrumb" class="mb-10">
|
||||
<a href="/ru/" class="inline-flex items-center gap-1.5 text-sm text-zinc-500 hover:text-zinc-200 transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-[#534AB7] rounded" aria-label="Все генераторы">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m15 18-6-6 6-6"/></svg>
|
||||
Все генераторы
|
||||
</a>
|
||||
</nav>
|
||||
<header class="mb-2">
|
||||
<div class="flex items-center gap-2 mb-4">
|
||||
<span class="inline-block w-2.5 h-2.5 rounded-full bg-[#534AB7]" aria-hidden="true"></span>
|
||||
<span class="text-sm font-medium text-zinc-400 uppercase tracking-widest">randify</span>
|
||||
</div>
|
||||
<h1 class="text-3xl sm:text-4xl font-bold text-zinc-100">Генератор лотереи</h1>
|
||||
<p class="mt-2 text-base text-zinc-400">{generator.ruDescription}</p>
|
||||
</header>
|
||||
<main><LotteryGenerator /></main>
|
||||
<div class="mt-12 flex justify-center"><AdBanner size="tile" /></div>
|
||||
<SeoBlock lang="ru" howTo={[
|
||||
'Укажите диапазон чисел в полях «От» и «До».',
|
||||
'Задайте количество чисел для розыгрыша.',
|
||||
'Нажмите «Тянуть» — выпавшие числа появятся на экране.',
|
||||
'Нажмите «Копировать», чтобы сохранить результат.',
|
||||
]} whenTo={[
|
||||
'Розыгрыш лотерейных номеров.',
|
||||
'Жеребьёвка участников конкурса.',
|
||||
'Случайный выбор нескольких уникальных чисел.',
|
||||
]} />
|
||||
</div>
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
import BaseLayout from '../../../layouts/BaseLayout.astro';
|
||||
import NumberGenerator from '../../../components/generators/NumberGenerator.astro';
|
||||
import AdBanner from '../../../components/AdBanner.astro';
|
||||
import SeoBlock from '../../../components/SeoBlock.astro';
|
||||
import { generators } from '../../../data/generators';
|
||||
|
||||
const generator = generators.find((g) => g.slug === 'numbers')!;
|
||||
---
|
||||
|
||||
<BaseLayout title={generator.ruSeoTitle} description={generator.ruSeoDescription} lang="ru">
|
||||
<div class="max-w-2xl mx-auto px-4 py-12 sm:py-20">
|
||||
<nav aria-label="Breadcrumb" class="mb-10">
|
||||
<a href="/ru/" class="inline-flex items-center gap-1.5 text-sm text-zinc-500 hover:text-zinc-200 transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-[#534AB7] rounded" aria-label="Все генераторы">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m15 18-6-6 6-6"/></svg>
|
||||
Все генераторы
|
||||
</a>
|
||||
</nav>
|
||||
<header class="mb-2">
|
||||
<div class="flex items-center gap-2 mb-4">
|
||||
<span class="inline-block w-2.5 h-2.5 rounded-full bg-[#534AB7]" aria-hidden="true"></span>
|
||||
<span class="text-sm font-medium text-zinc-400 uppercase tracking-widest">randify</span>
|
||||
</div>
|
||||
<h1 class="text-3xl sm:text-4xl font-bold text-zinc-100">Генератор чисел</h1>
|
||||
<p class="mt-2 text-base text-zinc-400">{generator.ruDescription}</p>
|
||||
</header>
|
||||
<main><NumberGenerator /></main>
|
||||
<div class="mt-12 flex justify-center"><AdBanner size="tile" /></div>
|
||||
<SeoBlock lang="ru" howTo={[
|
||||
'Введите минимальное значение в поле «От».',
|
||||
'Введите максимальное значение в поле «До».',
|
||||
'Нажмите «Сгенерировать» — случайное число появится мгновенно.',
|
||||
'Нажмите на число, чтобы скопировать его в буфер обмена.',
|
||||
]} whenTo={[
|
||||
'Выбор победителя в розыгрыше или конкурсе.',
|
||||
'Определение случайного первого игрока в настольной игре.',
|
||||
'Быстрое принятие решения между пронумерованными вариантами.',
|
||||
'Генерация тестовых данных с числами в заданном диапазоне.',
|
||||
]} />
|
||||
</div>
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
import BaseLayout from '../../../layouts/BaseLayout.astro';
|
||||
import PasswordGenerator from '../../../components/generators/PasswordGenerator.astro';
|
||||
import AdBanner from '../../../components/AdBanner.astro';
|
||||
import SeoBlock from '../../../components/SeoBlock.astro';
|
||||
import { generators } from '../../../data/generators';
|
||||
|
||||
const generator = generators.find((g) => g.slug === 'password')!;
|
||||
---
|
||||
|
||||
<BaseLayout title={generator.ruSeoTitle} description={generator.ruSeoDescription} lang="ru">
|
||||
<div class="max-w-2xl mx-auto px-4 py-12 sm:py-20">
|
||||
<nav aria-label="Breadcrumb" class="mb-10">
|
||||
<a href="/ru/" class="inline-flex items-center gap-1.5 text-sm text-zinc-500 hover:text-zinc-200 transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-[#534AB7] rounded" aria-label="Все генераторы">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m15 18-6-6 6-6"/></svg>
|
||||
Все генераторы
|
||||
</a>
|
||||
</nav>
|
||||
<header class="mb-2">
|
||||
<div class="flex items-center gap-2 mb-4">
|
||||
<span class="inline-block w-2.5 h-2.5 rounded-full bg-[#534AB7]" aria-hidden="true"></span>
|
||||
<span class="text-sm font-medium text-zinc-400 uppercase tracking-widest">randify</span>
|
||||
</div>
|
||||
<h1 class="text-3xl sm:text-4xl font-bold text-zinc-100">Генератор паролей</h1>
|
||||
<p class="mt-2 text-base text-zinc-400">{generator.ruDescription}</p>
|
||||
</header>
|
||||
<main><PasswordGenerator /></main>
|
||||
<div class="mt-12 flex justify-center"><AdBanner size="tile" /></div>
|
||||
<SeoBlock lang="ru" howTo={[
|
||||
'Задайте длину пароля с помощью ползунка.',
|
||||
'Выберите типы символов: заглавные, строчные, цифры, спецсимволы.',
|
||||
'Нажмите «Сгенерировать» — готовый пароль появится на экране.',
|
||||
'Нажмите на пароль, чтобы скопировать его.',
|
||||
]} whenTo={[
|
||||
'Создание надёжного пароля для нового аккаунта.',
|
||||
'Генерация секретного ключа или токена.',
|
||||
'Регулярное обновление паролей для повышения безопасности.',
|
||||
]} />
|
||||
</div>
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
import BaseLayout from '../../../layouts/BaseLayout.astro';
|
||||
import UuidGenerator from '../../../components/generators/UuidGenerator.astro';
|
||||
import AdBanner from '../../../components/AdBanner.astro';
|
||||
import SeoBlock from '../../../components/SeoBlock.astro';
|
||||
import { generators } from '../../../data/generators';
|
||||
|
||||
const generator = generators.find((g) => g.slug === 'uuid')!;
|
||||
---
|
||||
|
||||
<BaseLayout title={generator.ruSeoTitle} description={generator.ruSeoDescription} lang="ru">
|
||||
<div class="max-w-2xl mx-auto px-4 py-12 sm:py-20">
|
||||
<nav aria-label="Breadcrumb" class="mb-10">
|
||||
<a href="/ru/" class="inline-flex items-center gap-1.5 text-sm text-zinc-500 hover:text-zinc-200 transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-[#534AB7] rounded" aria-label="Все генераторы">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m15 18-6-6 6-6"/></svg>
|
||||
Все генераторы
|
||||
</a>
|
||||
</nav>
|
||||
<header class="mb-2">
|
||||
<div class="flex items-center gap-2 mb-4">
|
||||
<span class="inline-block w-2.5 h-2.5 rounded-full bg-[#534AB7]" aria-hidden="true"></span>
|
||||
<span class="text-sm font-medium text-zinc-400 uppercase tracking-widest">randify</span>
|
||||
</div>
|
||||
<h1 class="text-3xl sm:text-4xl font-bold text-zinc-100">Генератор UUID и токенов</h1>
|
||||
<p class="mt-2 text-base text-zinc-400">{generator.ruDescription}</p>
|
||||
</header>
|
||||
<main><UuidGenerator /></main>
|
||||
<div class="mt-12 flex justify-center"><AdBanner size="tile" /></div>
|
||||
<SeoBlock lang="ru" howTo={[
|
||||
'Выберите тип: UUID v4, Hex или Base64.',
|
||||
'Для Hex и Base64 задайте длину в байтах.',
|
||||
'Укажите количество токенов.',
|
||||
'Нажмите «Сгенерировать» и скопируйте результат.',
|
||||
]} whenTo={[
|
||||
'Генерация уникальных идентификаторов для баз данных.',
|
||||
'Создание токенов для API и сессий.',
|
||||
'Генерация случайных ключей шифрования.',
|
||||
]} />
|
||||
</div>
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
import BaseLayout from '../../../layouts/BaseLayout.astro';
|
||||
import WheelSpinner from '../../../components/generators/WheelSpinner.astro';
|
||||
import AdBanner from '../../../components/AdBanner.astro';
|
||||
import SeoBlock from '../../../components/SeoBlock.astro';
|
||||
import { generators } from '../../../data/generators';
|
||||
|
||||
const generator = generators.find((g) => g.slug === 'wheel')!;
|
||||
---
|
||||
|
||||
<BaseLayout title={generator.ruSeoTitle} description={generator.ruSeoDescription} lang="ru">
|
||||
<div class="max-w-2xl mx-auto px-4 py-12 sm:py-20">
|
||||
<nav aria-label="Breadcrumb" class="mb-10">
|
||||
<a href="/ru/" class="inline-flex items-center gap-1.5 text-sm text-zinc-500 hover:text-zinc-200 transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-[#534AB7] rounded" aria-label="Все генераторы">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m15 18-6-6 6-6"/></svg>
|
||||
Все генераторы
|
||||
</a>
|
||||
</nav>
|
||||
<header class="mb-2">
|
||||
<div class="flex items-center gap-2 mb-4">
|
||||
<span class="inline-block w-2.5 h-2.5 rounded-full bg-[#534AB7]" aria-hidden="true"></span>
|
||||
<span class="text-sm font-medium text-zinc-400 uppercase tracking-widest">randify</span>
|
||||
</div>
|
||||
<h1 class="text-3xl sm:text-4xl font-bold text-zinc-100">Колесо фортуны онлайн</h1>
|
||||
<p class="mt-2 text-base text-zinc-400">{generator.ruDescription}</p>
|
||||
</header>
|
||||
<main><WheelSpinner /></main>
|
||||
<div class="mt-12 flex justify-center"><AdBanner size="tile" /></div>
|
||||
<SeoBlock lang="ru" howTo={[
|
||||
'Введите варианты в поле — по одному на строку (от 2 до 24).',
|
||||
'Колесо обновляется автоматически.',
|
||||
'Нажмите «Крутить» и дождитесь результата.',
|
||||
'Победитель выделяется — скопируйте его кнопкой «Копировать».',
|
||||
]} whenTo={[
|
||||
'Случайный выбор победителя розыгрыша.',
|
||||
'Принятие решений в команде.',
|
||||
'Распределение ролей или задач между участниками.',
|
||||
]} />
|
||||
</div>
|
||||
</BaseLayout>
|
||||
Reference in New Issue
Block a user