diff --git a/assets/css/mineseeker/_overlay.scss b/assets/css/mineseeker/_overlay.scss index 3a94974..a6dfa9a 100644 --- a/assets/css/mineseeker/_overlay.scss +++ b/assets/css/mineseeker/_overlay.scss @@ -676,3 +676,96 @@ } } +// CaptchaOverlay Styles +.captcha-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(7, 9, 13, 0.95); + backdrop-filter: blur(8px); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; +} + +.captcha-content { + text-align: center; + color: #fff; + max-width: 400px; + padding: 40px; +} + +.captcha-icon { + font-size: 64px; + color: #236f87; + margin-bottom: 24px; +} + +.captcha-title { + font: 800 32px 'Rajdhani', sans-serif; + margin: 0 0 16px; + letter-spacing: 1px; +} + +.captcha-description { + color: rgba(149, 207, 245, 0.7); + font: 400 16px 'Rajdhani', sans-serif; + margin: 0 0 32px; + letter-spacing: 0.5px; +} + +.captcha-button { + background: linear-gradient(#236f87 0%, #1a5068 100%); + border: 2px solid #2e7a9a; + border-radius: 8px; + color: #e0f4ff; + cursor: pointer; + font: 800 18px 'Rajdhani', sans-serif; + letter-spacing: 2px; + padding: 16px 40px; + text-transform: uppercase; + transition: all 0.3s ease; + display: inline-flex; + align-items: center; + gap: 12px; + opacity: 1; + + i { + font-size: 16px; + } + + &:disabled { + opacity: 0.7; + cursor: wait; + } + + &:hover:not(:disabled) { + background: linear-gradient(#2d8aa8 0%, #236f87 100%); + border-color: #5ba4d4; + color: #fff; + box-shadow: 0 8px 24px rgba(35, 111, 135, 0.4); + transform: translateY(-2px); + } + + &:active:not(:disabled) { + transform: translateY(0); + } + + &.captcha-button--error { + background: linear-gradient(#8a2323 0%, #681a1a 100%); + border-color: #9a2e2e; + + &:hover { + background: linear-gradient(#a82d2d 0%, #872323 100%); + border-color: #d45b5b; + box-shadow: 0 8px 24px rgba(135, 35, 35, 0.4); + } + } + + &.captcha-button--loading { + opacity: 0.7; + } +} diff --git a/assets/js/mine-seeker/components/CaptchaOverlay.jsx b/assets/js/mine-seeker/components/CaptchaOverlay.jsx index 8993be4..22e4ad7 100644 --- a/assets/js/mine-seeker/components/CaptchaOverlay.jsx +++ b/assets/js/mine-seeker/components/CaptchaOverlay.jsx @@ -6,7 +6,8 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -import React, { useCallback, useEffect, useState } from 'react'; + +import React, { useCallback, useEffect, useMemo, useState } from 'react'; const CAPTCHA_STORAGE_KEY = 'mineseeker_captcha_verified'; const CAPTCHA_TOKEN_KEY = 'mineseeker_captcha_token'; @@ -17,6 +18,23 @@ const CaptchaOverlay = ({ siteKey, onVerified, children }) => { const [loading, setLoading] = useState(false); const [error, setError] = useState(false); + const handleToken = useCallback(token => { + const wrapper = document.getElementById('mine-wrapper'); + if (wrapper) { + wrapper.dataset.captchaToken = token; + } + sessionStorage.setItem(CAPTCHA_TOKEN_KEY, token); + sessionStorage.setItem(CAPTCHA_STORAGE_KEY, Date.now().toString()); + setVerified(true); + onVerified?.(); + }, [onVerified]); + + const buttonClasses = useMemo(() => [ + 'captcha-button', + error && 'captcha-button--error', + loading && 'captcha-button--loading', + ].filter(Boolean).join(' '), [error, loading]); + useEffect(() => { const storedToken = sessionStorage.getItem(CAPTCHA_TOKEN_KEY); const storedTime = sessionStorage.getItem(CAPTCHA_STORAGE_KEY); @@ -48,16 +66,6 @@ const CaptchaOverlay = ({ siteKey, onVerified, children }) => { } }, [siteKey, onVerified, handleToken]); - const handleToken = useCallback(token => { - const wrapper = document.getElementById('mine-wrapper'); - if (wrapper) { - wrapper.dataset.captchaToken = token; - } - sessionStorage.setItem(CAPTCHA_TOKEN_KEY, token); - sessionStorage.setItem(CAPTCHA_STORAGE_KEY, Date.now().toString()); - setVerified(true); - onVerified?.(); - }, [onVerified]); const handleClick = () => { setLoading(true); @@ -82,79 +90,18 @@ const CaptchaOverlay = ({ siteKey, onVerified, children }) => { return <>{children}; } - const overlayStyles = { - position: 'fixed', - top: 0, - left: 0, - width: '100%', - height: '100%', - background: 'rgba(7, 9, 13, 0.95)', - backdropFilter: 'blur(8px)', - display: 'flex', - alignItems: 'center', - justifyContent: 'center', - zIndex: 1000, - }; - - const contentStyles = { - textAlign: 'center', - color: '#fff', - maxWidth: '400px', - padding: '40px', - }; - - const iconStyles = { - fontSize: '64px', - color: '#236f87', - marginBottom: '24px', - }; - - const h1Styles = { - font: '800 32px Rajdhani, sans-serif', - margin: '0 0 16px', - letterSpacing: '1px', - }; - - const pStyles = { - color: 'rgba(149, 207, 245, 0.7)', - font: '400 16px Rajdhani, sans-serif', - margin: '0 0 32px', - letterSpacing: '0.5px', - }; - - const buttonStyles = { - background: error - ? 'linear-gradient(#8a2323 0%, #681a1a 100%)' - : loading - ? 'linear-gradient(#236f87 0%, #1a5068 100%)' - : 'linear-gradient(#236f87 0%, #1a5068 100%)', - border: `2px solid ${error ? '#9a2e2e' : loading ? '#2e7a9a' : '#2e7a9a'}`, - borderRadius: '8px', - color: '#e0f4ff', - cursor: loading ? 'wait' : 'pointer', - font: '800 18px Rajdhani, sans-serif', - letterSpacing: '2px', - padding: '16px 40px', - textTransform: 'uppercase', - transition: 'all 0.3s ease', - display: 'inline-flex', - alignItems: 'center', - gap: '12px', - opacity: loading ? 0.7 : 1, - }; - return ( -
-
-
+
+
+
-

Ready to Play?

-

+

Ready to Play?

+

Click below to verify you're human and start playing.