diff --git a/src/components/GeneratorCard.astro b/src/components/GeneratorCard.astro index 80a2fdc..0f09a1f 100644 --- a/src/components/GeneratorCard.astro +++ b/src/components/GeneratorCard.astro @@ -29,6 +29,12 @@ const icons: Record = { list: ``, fingerprint: ``, "pie-chart": ``, + "help-circle": ``, + user: ``, + users: ``, + type: ``, + calendar: ``, + hand: ``, }; --- diff --git a/src/components/LanguageSwitcher.astro b/src/components/LanguageSwitcher.astro index 8d464af..dfd9206 100644 --- a/src/components/LanguageSwitcher.astro +++ b/src/components/LanguageSwitcher.astro @@ -32,6 +32,13 @@ const alternatePath = isRu > {isRu ? "О проекте" : "About"} + + + {isRu ? "Конфиденциальность" : "Privacy"} + diff --git a/src/components/generators/LetterGenerator.astro b/src/components/generators/LetterGenerator.astro new file mode 100644 index 0000000..90b5752 --- /dev/null +++ b/src/components/generators/LetterGenerator.astro @@ -0,0 +1,120 @@ +--- +import { useT } from "../../i18n/translations"; +const isRu = Astro.url.pathname.startsWith("/ru"); +const T = useT(isRu ? "ru" : "en"); +--- + +
+
+
+ + {T.copied} +
+
+ +
+ +
+
+ + diff --git a/src/components/generators/NamesGenerator.astro b/src/components/generators/NamesGenerator.astro new file mode 100644 index 0000000..0486f41 --- /dev/null +++ b/src/components/generators/NamesGenerator.astro @@ -0,0 +1,217 @@ +--- +import { useT } from "../../i18n/translations"; +const isRu = Astro.url.pathname.startsWith("/ru"); +const T = useT(isRu ? "ru" : "en"); + +const genderOptions = [ + { value: "male", label: isRu ? "Мужские" : "Male" }, + { value: "female", label: isRu ? "Женские" : "Female" }, + { value: "any", label: isRu ? "Любые" : "Any" }, +]; +--- + +
+
+ +
+ { + genderOptions.map(({ value, label }, i) => ( + + )) + } +
+
+ +
+
+ + + {T.copied} +
+
+ +
+ +
+
+ + diff --git a/src/components/generators/RpsGenerator.astro b/src/components/generators/RpsGenerator.astro new file mode 100644 index 0000000..25f565b --- /dev/null +++ b/src/components/generators/RpsGenerator.astro @@ -0,0 +1,145 @@ +--- +import { useT } from "../../i18n/translations"; +const isRu = Astro.url.pathname.startsWith("/ru"); +const T = useT(isRu ? "ru" : "en"); +--- + +
+
+

+ {isRu ? "Выберите ваш вариант:" : "Pick your move:"} +

+
+ + + +
+
+ +
+
+

+ {isRu ? "Выберите ход, чтобы начать игру" : "Pick a move to start the game"} +

+ + +
+
+
+ + diff --git a/src/components/generators/TeamsGenerator.astro b/src/components/generators/TeamsGenerator.astro new file mode 100644 index 0000000..0f98249 --- /dev/null +++ b/src/components/generators/TeamsGenerator.astro @@ -0,0 +1,313 @@ +--- +import { useT } from "../../i18n/translations"; +const isRu = Astro.url.pathname.startsWith("/ru"); +const T = useT(isRu ? "ru" : "en"); + +const itemsPlaceholder = isRu + ? "Алиса\nБоб\nКарол\nДэвид" + : "Alice\nBob\nCarol\nDavid"; +const teamCountLabel = isRu ? "Количество команд" : "Number of teams"; +const teamPrefix = isRu ? "Команда" : "Team"; +const errAddTwo = isRu + ? "Добавьте хотя бы 2 участника." + : "Add at least 2 participants."; +const errTeamsMin = isRu + ? "Минимум 2 команды." + : "Minimum 2 teams."; +const errTeamsMax = isRu + ? "Максимум 20 команд." + : "Maximum 20 teams."; +const errMorePlayers = isRu + ? "Участников должно быть больше, чем команд." + : "Participants must outnumber teams."; +--- + +
+
+
+
+ + +
+ +
+ + +
+
+
+ + + +
+
+
+ + +
+ +
+ +
+
+ + diff --git a/src/components/generators/YesNoGenerator.astro b/src/components/generators/YesNoGenerator.astro new file mode 100644 index 0000000..0d4a0dc --- /dev/null +++ b/src/components/generators/YesNoGenerator.astro @@ -0,0 +1,182 @@ +--- +import { useT } from "../../i18n/translations"; +const isRu = Astro.url.pathname.startsWith("/ru"); +const T = useT(isRu ? "ru" : "en"); + +const askPlaceholder = isRu ? "Задайте вопрос..." : "Ask anything..."; +const getAnswerLabel = isRu ? "Получить ответ" : "Get Answer"; +const confidenceLabel = isRu ? "Уверенность" : "Confidence"; +--- + +
+
+ + +
+ +
+
+ + + + + {T.copied} +
+
+ +
+ +
+
+ + diff --git a/src/content/generators/date.json b/src/content/generators/date.json new file mode 100644 index 0000000..801f28d --- /dev/null +++ b/src/content/generators/date.json @@ -0,0 +1,47 @@ +{ + "slug": "date", + "title": "Random Date", + "description": "Generate a random date between any two dates you choose.", + "icon": "calendar", + "status": "live", + "seoTitle": "Random Date Generator — Between Two Dates | Randify", + "seoDescription": "Generate a random date between any two dates instantly. Free online date picker for planning, games, and creative projects.", + "ruTitle": "Случайная дата", + "ruDescription": "Сгенерируйте случайную дату между любыми двумя датами.", + "ruSeoTitle": "Генератор случайных дат — между двумя датами | Randify", + "ruSeoDescription": "Сгенерируйте случайную дату в любом диапазоне мгновенно. Бесплатный инструмент для планирования, игр и творческих задач.", + "pageTitle": "Random Date Generator", + "ruPageTitle": "Генератор случайных дат", + "howTo": [ + "Select the start date in the From field.", + "Select the end date in the To field.", + "Click Generate — a random date within your range appears instantly.", + "Click the date to copy it to your clipboard." + ], + "whenTo": [ + "Picking a random deadline or milestone for a challenge.", + "Choosing a date for a hypothetical scenario or story setting.", + "Generating random historical dates for a quiz or trivia game." + ], + "ruHowTo": [ + "Выберите начальную дату в поле «От».", + "Выберите конечную дату в поле «До».", + "Нажмите «Сгенерировать» — случайная дата в диапазоне появится мгновенно.", + "Нажмите на дату, чтобы скопировать её в буфер обмена." + ], + "ruWhenTo": [ + "Выбор случайного дедлайна или вехи для челленджа.", + "Определение даты для гипотетического сценария или сюжета.", + "Генерация случайных исторических дат для викторины или игры." + ], + "faq": [ + { "q": "What date format is used?", "a": "Dates are displayed in a clear, locale-friendly format. You can copy the value and paste it wherever you need." }, + { "q": "Can I generate multiple random dates?", "a": "Currently, one date is generated per click. Click again to get another random date in the same range." }, + { "q": "Is the selection truly random?", "a": "Yes. The date is picked using a cryptographically secure random number generator, so every day in your range has an equal chance." } + ], + "ruFaq": [ + { "q": "Какой формат даты используется?", "a": "Даты отображаются в удобном локализованном формате. Вы можете скопировать значение и вставить его куда угодно." }, + { "q": "Можно ли сгенерировать несколько дат сразу?", "a": "Сейчас генерируется одна дата за раз. Нажмите снова, чтобы получить ещё одну случайную дату в том же диапазоне." }, + { "q": "Выбор действительно случайный?", "a": "Да. Дата выбирается с помощью криптографически стойкого генератора случайных чисел, поэтому каждый день в диапазоне имеет равный шанс." } + ] +} diff --git a/src/content/generators/letter.json b/src/content/generators/letter.json new file mode 100644 index 0000000..0c70188 --- /dev/null +++ b/src/content/generators/letter.json @@ -0,0 +1,47 @@ +{ + "slug": "letter", + "title": "Random Letter", + "description": "Pick a random letter from the alphabet.", + "icon": "type", + "status": "live", + "seoTitle": "Random Letter Generator — A to Z | Randify", + "seoDescription": "Pick a random letter from A to Z instantly. Free online letter randomizer for games, learning, and creative projects.", + "ruTitle": "Случайная буква", + "ruDescription": "Выберите случайную букву из алфавита.", + "ruSeoTitle": "Генератор случайных букв — А до Я | Randify", + "ruSeoDescription": "Выберите случайную букву алфавита мгновенно. Бесплатный рандомайзер букв для игр, обучения и творческих проектов.", + "pageTitle": "Random Letter Generator", + "ruPageTitle": "Генератор случайных букв", + "howTo": [ + "Click Generate to pick a random letter from A to Z.", + "The letter appears in large type for easy reading.", + "Click the letter to copy it to your clipboard.", + "Click again to generate a new random letter." + ], + "whenTo": [ + "Choosing a starting letter for a word game or alphabet challenge.", + "Picking a random category in a trivia or party game.", + "Teaching children letters and the alphabet in a fun way." + ], + "ruHowTo": [ + "Нажмите «Сгенерировать», чтобы выбрать случайную букву от А до Я.", + "Буква отображается крупным шрифтом для удобного чтения.", + "Нажмите на букву, чтобы скопировать её в буфер обмена.", + "Нажмите снова, чтобы сгенерировать новую случайную букву." + ], + "ruWhenTo": [ + "Выбор стартовой буквы для словесной игры или алфавитного челленджа.", + "Случайный выбор категории в викторине или настольной игре.", + "Обучение детей буквам и алфавиту в игровой форме." + ], + "faq": [ + { "q": "Does it include both uppercase and lowercase letters?", "a": "The generator produces uppercase letters by default. Lowercase is not currently supported." }, + { "q": "Can I exclude certain letters?", "a": "Not at the moment. Every letter from A to Z has an equal chance of being selected." }, + { "q": "Is this useful for language learning?", "a": "Yes. Teachers and students use it for alphabet drills, vocabulary games, and pronunciation practice." } + ], + "ruFaq": [ + { "q": "Включает ли генератор заглавные и строчные буквы?", "a": "Генератор выдаёт заглавные буквы по умолчанию. Строчные буквы пока не поддерживаются." }, + { "q": "Можно ли исключить определённые буквы?", "a": "Пока нет. Каждая буква от А до Я имеет равный шанс быть выбранной." }, + { "q": "Подходит ли для изучения языка?", "a": "Да. Учителя и ученики используют генератор для алфавитных упражнений, словарных игр и практики произношения." } + ] +} diff --git a/src/content/generators/names.json b/src/content/generators/names.json new file mode 100644 index 0000000..2b6d23c --- /dev/null +++ b/src/content/generators/names.json @@ -0,0 +1,47 @@ +{ + "slug": "names", + "title": "Random Name", + "description": "Generate a random first name by gender or any category.", + "icon": "user", + "status": "live", + "seoTitle": "Random Name Generator — First Names | Randify", + "seoDescription": "Generate random first names instantly. Pick male, female, or any names for characters, babies, games, and more.", + "ruTitle": "Случайное имя", + "ruDescription": "Сгенерируйте случайное имя по полу или из общего списка.", + "ruSeoTitle": "Генератор случайных имён | Randify", + "ruSeoDescription": "Генератор случайных имён: мужские, женские, любые. Для персонажей, игр, вдохновения и не только.", + "pageTitle": "Random Name Generator", + "ruPageTitle": "Генератор случайных имён", + "howTo": [ + "Select a category: Male, Female, or Any.", + "Click Generate to produce a random name.", + "The name appears instantly on the screen.", + "Click the name to copy it to your clipboard." + ], + "whenTo": [ + "Naming a character in a story, game, or RPG campaign.", + "Looking for baby name inspiration.", + "Generating placeholder names for mockups or test data." + ], + "ruHowTo": [ + "Выберите категорию: Мужские, Женские или Любые.", + "Нажмите «Сгенерировать», чтобы получить случайное имя.", + "Имя появится на экране мгновенно.", + "Нажмите на имя, чтобы скопировать его в буфер обмена." + ], + "ruWhenTo": [ + "Придумывание имени персонажа для рассказа, игры или НРИ.", + "Поиск вдохновения для имени ребёнка.", + "Генерация тестовых данных с реалистичными именами." + ], + "faq": [ + { "q": "How many names are in the database?", "a": "Hundreds of popular first names are included, covering common choices in English and Russian." }, + { "q": "Can I generate multiple names at once?", "a": "Currently, one name is shown per click. You can click Generate as many times as you like." }, + { "q": "Are the names culturally specific?", "a": "The list includes widely used names. Some may be more common in certain regions, but all are familiar internationally." } + ], + "ruFaq": [ + { "q": "Сколько имён в базе?", "a": "В базе сотни популярных имён, включая распространённые варианты на английском и русском языках." }, + { "q": "Можно ли сгенерировать несколько имён сразу?", "a": "Сейчас показывается одно имя за раз. Вы можете нажимать «Сгенерировать» столько раз, сколько нужно." }, + { "q": "Имена привязаны к конкретной культуре?", "a": "В списке широко распространённые имена. Некоторые чаще встречаются в определённых регионах, но все они международно узнаваемы." } + ] +} diff --git a/src/content/generators/rps.json b/src/content/generators/rps.json new file mode 100644 index 0000000..2a5b3ee --- /dev/null +++ b/src/content/generators/rps.json @@ -0,0 +1,47 @@ +{ + "slug": "rps", + "title": "Rock Paper Scissors", + "description": "Play Rock Paper Scissors against a random computer opponent.", + "icon": "hand", + "status": "live", + "seoTitle": "Rock Paper Scissors — Play Online | Randify", + "seoDescription": "Play Rock Paper Scissors online against a random computer opponent. Free, instant, and fair — no account needed.", + "ruTitle": "Камень Ножницы Бумага", + "ruDescription": "Сыграйте в Камень Ножницы Бумага против случайного компьютерного соперника.", + "ruSeoTitle": "Камень Ножницы Бумага — играть онлайн | Randify", + "ruSeoDescription": "Играйте в Камень Ножницы Бумага онлайн против компьютера. Бесплатно, мгновенно и честно — без регистрации.", + "pageTitle": "Rock Paper Scissors", + "ruPageTitle": "Камень Ножницы Бумага", + "howTo": [ + "Choose your move: Rock, Paper, or Scissors.", + "Click Play — the computer makes its random choice.", + "The result is shown instantly: win, lose, or draw.", + "Play again as many times as you like." + ], + "whenTo": [ + "Making a quick decision with a friend when neither wants to choose.", + "Killing time with a simple, familiar game.", + "Settling a tie or breaking a deadlock in any activity." + ], + "ruHowTo": [ + "Выберите свой ход: Камень, Ножницы или Бумага.", + "Нажмите «Играть» — компьютер делает случайный выбор.", + "Результат отображается мгновенно: победа, поражение или ничья.", + "Играйте снова сколько угодно раз." + ], + "ruWhenTo": [ + "Быстрое решение спора с другом, когда никто не хочет выбирать первым.", + "Коротание времени в простой и знакомой игре.", + "Разрешение ничьей или выход из тупика в любой активности." + ], + "faq": [ + { "q": "Is the computer choice truly random?", "a": "Yes. The computer's move is generated using a cryptographically secure random number generator, making every round fair and unpredictable." }, + { "q": "Can I play multiple rounds and track my score?", "a": "Currently, each round is independent. A score tracker may be added in a future update." }, + { "q": "Does the computer learn from my moves?", "a": "No. Each move is completely independent and random. The computer does not adapt or remember your previous choices." } + ], + "ruFaq": [ + { "q": "Выбор компьютера действительно случайный?", "a": "Да. Ход компьютера генерируется с помощью криптографически стойкого генератора случайных чисел, делая каждый раунд честным и непредсказуемым." }, + { "q": "Можно ли играть несколько раундов и вести счёт?", "a": "Сейчас каждый раунд независим. Счётчик побед может появиться в будущем обновлении." }, + { "q": "Учится ли компьютер на моих ходах?", "a": "Нет. Каждый ход полностью независимый и случайный. Компьютер не адаптируется и не запоминает ваши предыдущие выборы." } + ] +} diff --git a/src/content/generators/teams.json b/src/content/generators/teams.json new file mode 100644 index 0000000..9b629bf --- /dev/null +++ b/src/content/generators/teams.json @@ -0,0 +1,47 @@ +{ + "slug": "teams", + "title": "Team Splitter", + "description": "Split a list of people into random teams or groups.", + "icon": "users", + "status": "live", + "seoTitle": "Random Team Generator — Split into Groups | Randify", + "seoDescription": "Split any list of names into random teams instantly. Perfect for sports, workshops, classrooms, and party games.", + "ruTitle": "Разделение на команды", + "ruDescription": "Разделите список людей на случайные команды или группы.", + "ruSeoTitle": "Генератор случайных команд — разделение на группы | Randify", + "ruSeoDescription": "Разделите любой список имён на случайные команды мгновенно. Для спорта, занятий, воркшопов и вечеринок.", + "pageTitle": "Random Team Generator", + "ruPageTitle": "Генератор случайных команд", + "howTo": [ + "Enter the list of participants — one name per line.", + "Set the number of teams you want to create.", + "Click Generate — the tool shuffles and splits the list evenly.", + "Review the teams and copy or share the results." + ], + "whenTo": [ + "Organising random teams for a sports match or tournament.", + "Splitting a class or workshop into balanced groups.", + "Creating teams for a party game or team-building activity." + ], + "ruHowTo": [ + "Введите список участников — по одному имени на строку.", + "Укажите количество команд, которые нужно создать.", + "Нажмите «Сгенерировать» — инструмент перемешает и равномерно разделит список.", + "Просмотрите команды и скопируйте или поделитесь результатами." + ], + "ruWhenTo": [ + "Формирование случайных команд для спортивной игры или турнира.", + "Разделение класса или воркшопа на сбалансированные группы.", + "Создание команд для игры на вечеринке или тимбилдинга." + ], + "faq": [ + { "q": "What happens if the list cannot be divided evenly?", "a": "Teams are created as evenly as possible. If there is a remainder, some teams will have one extra member." }, + { "q": "Is there a limit to the number of participants?", "a": "You can add up to 500 names. For most events and activities, this limit is more than sufficient." }, + { "q": "Can I use this for non-name lists?", "a": "Yes. You can split any text items — tasks, topics, or objects — into random groups." } + ], + "ruFaq": [ + { "q": "Что если список нельзя разделить поровну?", "a": "Команды формируются максимально равномерно. Если остаётся остаток, некоторые команды будут на одного участника больше." }, + { "q": "Есть ли ограничение на количество участников?", "a": "Можно добавить до 500 имён. Для большинства мероприятий и активностей этого более чем достаточно." }, + { "q": "Можно ли использовать не только для имён?", "a": "Да. Вы можете разделить на группы любые текстовые элементы — задачи, темы или предметы." } + ] +} diff --git a/src/content/generators/yesno.json b/src/content/generators/yesno.json new file mode 100644 index 0000000..a1735dd --- /dev/null +++ b/src/content/generators/yesno.json @@ -0,0 +1,47 @@ +{ + "slug": "yesno", + "title": "Yes or No", + "description": "Get a random Yes, No, or Maybe answer to any question.", + "icon": "help-circle", + "status": "live", + "seoTitle": "Yes or No Generator — Random Answer | Randify", + "seoDescription": "Get an instant random Yes, No, or Maybe answer to any question. Free online decision maker when you need a quick verdict.", + "ruTitle": "Да или Нет", + "ruDescription": "Получите случайный ответ Да, Нет или Возможно на любой вопрос.", + "ruSeoTitle": "Генератор Да или Нет — случайный ответ | Randify", + "ruSeoDescription": "Мгновенный случайный ответ Да, Нет или Возможно на любой вопрос. Бесплатный онлайн-помощник для быстрых решений.", + "pageTitle": "Yes or No Generator", + "ruPageTitle": "Генератор Да или Нет", + "howTo": [ + "Type your question in the field (optional — it is just for context).", + "Click the button to get a random answer.", + "The result appears instantly: Yes, No, or Maybe.", + "A confidence percentage is shown alongside the answer." + ], + "whenTo": [ + "Making a trivial decision when you are stuck.", + "Settling a friendly debate or bet.", + "Adding a fun random element to a game or challenge." + ], + "ruHowTo": [ + "Введите свой вопрос в поле (по желанию — это просто для контекста).", + "Нажмите кнопку, чтобы получить случайный ответ.", + "Результат появится мгновенно: Да, Нет или Возможно.", + "Рядом с ответом отображается процент уверенности." + ], + "ruWhenTo": [ + "Принятие простого решения, когда вы не можете выбрать.", + "Разрешение дружеского спора или пари.", + "Добавление случайного элемента в игру или челлендж." + ], + "faq": [ + { "q": "Is the answer really random?", "a": "Yes. The outcome is generated using a cryptographically secure random number generator, giving each option a fair chance." }, + { "q": "What does the confidence percentage mean?", "a": "It is a fun visual indicator showing how 'certain' the random choice feels — it does not affect the actual result." }, + { "q": "Can I use this for serious decisions?", "a": "It is best for light-hearted or trivial choices. For important matters, trust your own judgment." } + ], + "ruFaq": [ + { "q": "Ответ действительно случайный?", "a": "Да. Результат генерируется с помощью криптографически стойкого генератора случайных чисел, давая каждому варианту равный шанс." }, + { "q": "Что означает процент уверенности?", "a": "Это забавный визуальный индикатор, показывающий, насколько «уверен» случайный выбор — он не влияет на сам результат." }, + { "q": "Можно ли использовать для серьёзных решений?", "a": "Лучше всего подходит для лёгких или шуточных выборов. В важных вопросах доверяйте собственному мнению." } + ] +} diff --git a/src/i18n/translations.ts b/src/i18n/translations.ts index 6e3b8d3..1592a7b 100644 --- a/src/i18n/translations.ts +++ b/src/i18n/translations.ts @@ -80,6 +80,20 @@ export const translations = { "Have a suggestion, found a bug, or just want to say hello? Drop us a line at hello@randify.pro — we read every message.", aboutCta: "Ready to give it a spin? Explore the generators and let chance do the work.", + + privacyTitle: "Privacy Policy", + privacyIntro: + "This Privacy Policy explains how Randify handles information when you use our website. We believe in transparency: we collect as little data as possible and never ask for personal information.", + privacyData: + "Randify does not collect, store, or process any personal data. All random values — numbers, passwords, dice rolls, card draws, and every other result — are generated entirely inside your browser. Nothing you enter or generate is sent to our servers. We do not require registration, we do not ask for your name or email to use the generators, and we have no access to your inputs or outputs.", + privacyCookies: + "We do not use tracking cookies. The only information stored on your device is your language preference (English or Russian), which is saved in localStorage so the site remembers your choice on future visits. This data never leaves your browser and is not shared with anyone.", + privacyThirdParty: + "We use two third-party services to keep Randify free and improve the experience:\n\n• Yandex.RTB — displays advertisements on some pages. Yandex may use cookies and similar technologies to show relevant ads. You can manage ad preferences through your browser settings or Yandex's opt-out tools.\n\n• Yandex.Metrika — helps us understand how visitors use the site (for example, which generators are most popular). This is anonymous aggregate data: we cannot identify individual users.", + privacyContact: + "If you have any questions about this policy or how we handle data, please contact us at hello@randify.pro.", + privacyChanges: + "We may update this Privacy Policy from time to time. Any changes will be posted on this page with an updated date. Since we do not collect contact information, we cannot notify users individually — please check this page occasionally for updates.", }, ru: { allGenerators: "Все генераторы", @@ -160,6 +174,20 @@ export const translations = { "Есть предложение, нашли ошибку или просто хотите поздороваться? Напишите нам на hello@randify.pro — мы читаем каждое сообщение.", aboutCta: "Готовы попробовать? Откройте генераторы и позвольте случайности сделать выбор за вас.", + + privacyTitle: "Политика конфиденциальности", + privacyIntro: + "Настоящая Политика конфиденциальности объясняет, как Randify работает с информацией при использовании сайта. Мы верим в прозрачность: собираем минимум данных и никогда не запрашиваем персональную информацию.", + privacyData: + "Randify не собирает, не хранит и не обрабатывает персональные данные. Все случайные значения — числа, пароли, броски кубиков, вытягивание карт и любые другие результаты — генерируются полностью внутри вашего браузера. Ничто из того, что вы вводите или генерируете, не отправляется на наши серверы. Мы не требуем регистрации, не просим имя или email для использования генераторов и не имеем доступа к вашим данным.", + privacyCookies: + "Мы не используем cookies для отслеживания. Единственная информация, которая сохраняется на вашем устройстве, — это предпочитаемый язык (английский или русский) в localStorage, чтобы сайт запоминал ваш выбор при следующем посещении. Эти данные не покидают браузер и никому не передаются.", + privacyThirdParty: + "Мы используем два сторонних сервиса, чтобы Randify оставался бесплатным и удобным:\n\n• Yandex.RTB — показывает рекламу на некоторых страницах. Яндекс может использовать cookies и аналогичные технологии для показа релевантной рекламы. Вы можете управлять настройками рекламы через параметры браузера или инструменты отказа Яндекса.\n\n• Яндекс.Метрика — помогает нам понимать, как посетители используют сайт (например, какие генераторы самые популярные). Это анонимные агрегированные данные: мы не можем идентифицировать отдельных пользователей.", + privacyContact: + "Если у вас есть вопросы об этой политике или о том, как мы работаем с данными, напишите нам на hello@randify.pro.", + privacyChanges: + "Мы можем обновлять эту Политику конфиденциальности время от времени. Любые изменения будут опубликованы на этой странице с обновлённой датой. Поскольку мы не собираем контактную информацию, мы не можем уведомлять пользователей индивидуально — пожалуйста, проверяйте эту страницу время от времени.", }, } as const; diff --git a/src/pages/generators/date.astro b/src/pages/generators/date.astro new file mode 100644 index 0000000..66627e7 --- /dev/null +++ b/src/pages/generators/date.astro @@ -0,0 +1,11 @@ +--- +import GeneratorLayout from '@/layouts/GeneratorLayout.astro'; +import DateGenerator from '@/components/generators/DateGenerator.astro'; +import { generators } from '@/data/generators'; + +const generator = generators.find((g) => g.slug === 'date')!; +--- + + + + diff --git a/src/pages/generators/letter.astro b/src/pages/generators/letter.astro new file mode 100644 index 0000000..05b5c6e --- /dev/null +++ b/src/pages/generators/letter.astro @@ -0,0 +1,11 @@ +--- +import GeneratorLayout from '@/layouts/GeneratorLayout.astro'; +import LetterGenerator from '@/components/generators/LetterGenerator.astro'; +import { generators } from '@/data/generators'; + +const generator = generators.find((g) => g.slug === 'letter')!; +--- + + + + diff --git a/src/pages/generators/names.astro b/src/pages/generators/names.astro new file mode 100644 index 0000000..446a342 --- /dev/null +++ b/src/pages/generators/names.astro @@ -0,0 +1,11 @@ +--- +import GeneratorLayout from '@/layouts/GeneratorLayout.astro'; +import NamesGenerator from '@/components/generators/NamesGenerator.astro'; +import { generators } from '@/data/generators'; + +const generator = generators.find((g) => g.slug === 'names')!; +--- + + + + diff --git a/src/pages/generators/rps.astro b/src/pages/generators/rps.astro new file mode 100644 index 0000000..ea634fc --- /dev/null +++ b/src/pages/generators/rps.astro @@ -0,0 +1,11 @@ +--- +import GeneratorLayout from '@/layouts/GeneratorLayout.astro'; +import RpsGenerator from '@/components/generators/RpsGenerator.astro'; +import { generators } from '@/data/generators'; + +const generator = generators.find((g) => g.slug === 'rps')!; +--- + + + + diff --git a/src/pages/generators/teams.astro b/src/pages/generators/teams.astro new file mode 100644 index 0000000..3680f99 --- /dev/null +++ b/src/pages/generators/teams.astro @@ -0,0 +1,11 @@ +--- +import GeneratorLayout from '@/layouts/GeneratorLayout.astro'; +import TeamsGenerator from '@/components/generators/TeamsGenerator.astro'; +import { generators } from '@/data/generators'; + +const generator = generators.find((g) => g.slug === 'teams')!; +--- + + + + diff --git a/src/pages/generators/yesno.astro b/src/pages/generators/yesno.astro new file mode 100644 index 0000000..d477485 --- /dev/null +++ b/src/pages/generators/yesno.astro @@ -0,0 +1,11 @@ +--- +import GeneratorLayout from '@/layouts/GeneratorLayout.astro'; +import YesNoGenerator from '@/components/generators/YesNoGenerator.astro'; +import { generators } from '@/data/generators'; + +const generator = generators.find((g) => g.slug === 'yesno')!; +--- + + + + diff --git a/src/pages/privacy.astro b/src/pages/privacy.astro new file mode 100644 index 0000000..796bf2b --- /dev/null +++ b/src/pages/privacy.astro @@ -0,0 +1,85 @@ +--- +import BaseLayout from "@/layouts/BaseLayout.astro"; +import { useT } from "@/i18n/translations"; +import type { Lang } from "@/i18n/translations"; + +const lang = (Astro.currentLocale as Lang) || "en"; +const T = useT(lang); +--- + + +
+ + +
+
+ + randify +
+

+ {T.privacyTitle} +

+ +
+ +
+
+

{T.privacyIntro}

+
+ +
+

Data Collection

+

{T.privacyData}

+
+ +
+

Cookies & Local Storage

+

{T.privacyCookies}

+
+ +
+

Third-Party Services

+ {T.privacyThirdParty.split("\n\n").map((paragraph) => ( +

{paragraph}

+ ))} +
+ +
+

Contact

+

{T.privacyContact}

+
+ +
+

Changes to This Policy

+

{T.privacyChanges}

+
+
+
+
diff --git a/src/pages/ru/generators/date.astro b/src/pages/ru/generators/date.astro new file mode 100644 index 0000000..66627e7 --- /dev/null +++ b/src/pages/ru/generators/date.astro @@ -0,0 +1,11 @@ +--- +import GeneratorLayout from '@/layouts/GeneratorLayout.astro'; +import DateGenerator from '@/components/generators/DateGenerator.astro'; +import { generators } from '@/data/generators'; + +const generator = generators.find((g) => g.slug === 'date')!; +--- + + + + diff --git a/src/pages/ru/generators/letter.astro b/src/pages/ru/generators/letter.astro new file mode 100644 index 0000000..05b5c6e --- /dev/null +++ b/src/pages/ru/generators/letter.astro @@ -0,0 +1,11 @@ +--- +import GeneratorLayout from '@/layouts/GeneratorLayout.astro'; +import LetterGenerator from '@/components/generators/LetterGenerator.astro'; +import { generators } from '@/data/generators'; + +const generator = generators.find((g) => g.slug === 'letter')!; +--- + + + + diff --git a/src/pages/ru/generators/names.astro b/src/pages/ru/generators/names.astro new file mode 100644 index 0000000..446a342 --- /dev/null +++ b/src/pages/ru/generators/names.astro @@ -0,0 +1,11 @@ +--- +import GeneratorLayout from '@/layouts/GeneratorLayout.astro'; +import NamesGenerator from '@/components/generators/NamesGenerator.astro'; +import { generators } from '@/data/generators'; + +const generator = generators.find((g) => g.slug === 'names')!; +--- + + + + diff --git a/src/pages/ru/generators/rps.astro b/src/pages/ru/generators/rps.astro new file mode 100644 index 0000000..ea634fc --- /dev/null +++ b/src/pages/ru/generators/rps.astro @@ -0,0 +1,11 @@ +--- +import GeneratorLayout from '@/layouts/GeneratorLayout.astro'; +import RpsGenerator from '@/components/generators/RpsGenerator.astro'; +import { generators } from '@/data/generators'; + +const generator = generators.find((g) => g.slug === 'rps')!; +--- + + + + diff --git a/src/pages/ru/generators/teams.astro b/src/pages/ru/generators/teams.astro new file mode 100644 index 0000000..3680f99 --- /dev/null +++ b/src/pages/ru/generators/teams.astro @@ -0,0 +1,11 @@ +--- +import GeneratorLayout from '@/layouts/GeneratorLayout.astro'; +import TeamsGenerator from '@/components/generators/TeamsGenerator.astro'; +import { generators } from '@/data/generators'; + +const generator = generators.find((g) => g.slug === 'teams')!; +--- + + + + diff --git a/src/pages/ru/generators/yesno.astro b/src/pages/ru/generators/yesno.astro new file mode 100644 index 0000000..d477485 --- /dev/null +++ b/src/pages/ru/generators/yesno.astro @@ -0,0 +1,11 @@ +--- +import GeneratorLayout from '@/layouts/GeneratorLayout.astro'; +import YesNoGenerator from '@/components/generators/YesNoGenerator.astro'; +import { generators } from '@/data/generators'; + +const generator = generators.find((g) => g.slug === 'yesno')!; +--- + + + + diff --git a/src/pages/ru/privacy.astro b/src/pages/ru/privacy.astro new file mode 100644 index 0000000..fb85f63 --- /dev/null +++ b/src/pages/ru/privacy.astro @@ -0,0 +1,85 @@ +--- +import BaseLayout from "@/layouts/BaseLayout.astro"; +import { useT } from "@/i18n/translations"; +import type { Lang } from "@/i18n/translations"; + +const lang = (Astro.currentLocale as Lang) || "en"; +const T = useT(lang); +--- + + +
+ + +
+
+ + randify +
+

+ {T.privacyTitle} +

+ +
+ +
+
+

{T.privacyIntro}

+
+ +
+

Сбор данных

+

{T.privacyData}

+
+ +
+

Cookies и локальное хранилище

+

{T.privacyCookies}

+
+ +
+

Сторонние сервисы

+ {T.privacyThirdParty.split("\n\n").map((paragraph) => ( +

{paragraph}

+ ))} +
+ +
+

Контакты

+

{T.privacyContact}

+
+ +
+

Изменения политики

+

{T.privacyChanges}

+
+
+
+