Watchlist: Fixed layout order + TLD Detail: Full techy mobile design
Some checks failed
CI / Frontend Lint & Type Check (push) Has been cancelled
CI / Frontend Build (push) Has been cancelled
CI / Backend Lint (push) Has been cancelled
CI / Backend Tests (push) Has been cancelled
CI / Docker Build (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
Deploy / Build & Push Images (push) Has been cancelled
Deploy / Deploy to Server (push) Has been cancelled
Deploy / Notify (push) Has been cancelled

This commit is contained in:
2025-12-13 15:22:45 +01:00
parent d56081aca0
commit 6a56360f56
4 changed files with 594 additions and 424 deletions

View File

@ -811,7 +811,7 @@ async def test_email(
"""Send a test email to the admin user.""" """Send a test email to the admin user."""
from app.services.email_service import email_service from app.services.email_service import email_service
if not email_service.is_configured: if not email_service.is_configured():
raise HTTPException( raise HTTPException(
status_code=400, status_code=400,
detail="Email service is not configured. Check SMTP settings." detail="Email service is not configured. Check SMTP settings."

View File

@ -160,7 +160,7 @@ async def register(
await db.commit() await db.commit()
# Send verification email in background # Send verification email in background
if email_service.is_configured: if email_service.is_configured():
site_url = os.getenv("SITE_URL", "http://localhost:3000") site_url = os.getenv("SITE_URL", "http://localhost:3000")
verify_url = f"{site_url}/verify-email?token={verification_token}" verify_url = f"{site_url}/verify-email?token={verification_token}"
@ -312,7 +312,7 @@ async def forgot_password(
await db.commit() await db.commit()
# Send reset email in background # Send reset email in background
if email_service.is_configured: if email_service.is_configured():
site_url = os.getenv("SITE_URL", "http://localhost:3000") site_url = os.getenv("SITE_URL", "http://localhost:3000")
reset_url = f"{site_url}/reset-password?token={reset_token}" reset_url = f"{site_url}/reset-password?token={reset_token}"
@ -440,7 +440,7 @@ async def resend_verification(
await db.commit() await db.commit()
# Send verification email # Send verification email
if email_service.is_configured: if email_service.is_configured():
site_url = os.getenv("SITE_URL", "http://localhost:3000") site_url = os.getenv("SITE_URL", "http://localhost:3000")
verify_url = f"{site_url}/verify-email?token={verification_token}" verify_url = f"{site_url}/verify-email?token={verification_token}"

File diff suppressed because it is too large Load Diff

View File

@ -327,10 +327,41 @@ export default function WatchlistPage() {
</header> </header>
{/* ═══════════════════════════════════════════════════════════════════════ */} {/* ═══════════════════════════════════════════════════════════════════════ */}
{/* ADD DOMAIN */} {/* DESKTOP HEADER */}
{/* ═══════════════════════════════════════════════════════════════════════ */} {/* ═══════════════════════════════════════════════════════════════════════ */}
<section className="px-4 lg:px-10 py-4"> <section className="hidden lg:block px-10 pt-10 pb-6">
<form onSubmit={handleAdd} className="relative"> <div className="flex flex-col lg:flex-row lg:items-end lg:justify-between gap-6">
<div className="space-y-3">
<div className="flex items-center gap-2">
<div className="w-1.5 h-1.5 bg-accent animate-pulse" />
<span className="text-[10px] font-mono tracking-[0.2em] text-accent uppercase">Domain Surveillance</span>
</div>
<h1 className="font-display text-[2.5rem] leading-[1] tracking-[-0.02em]">
<span className="text-white">Watchlist</span>
<span className="text-white/30 ml-3 font-mono text-[2rem]">{stats.total}</span>
</h1>
</div>
<div className="flex gap-8">
<div className="text-right">
<div className="text-2xl font-bold text-accent font-mono">{stats.available}</div>
<div className="text-[9px] font-mono text-white/30 uppercase tracking-wider">Available</div>
</div>
<div className="text-right">
<div className="text-2xl font-bold text-orange-400 font-mono">{stats.expiring}</div>
<div className="text-[9px] font-mono text-white/30 uppercase tracking-wider">Expiring</div>
</div>
</div>
</div>
</section>
{/* ═══════════════════════════════════════════════════════════════════════ */}
{/* ADD DOMAIN + FILTERS */}
{/* ═══════════════════════════════════════════════════════════════════════ */}
<section className="px-4 lg:px-10 py-4 border-b border-white/[0.08]">
{/* Add Domain Form */}
<form onSubmit={handleAdd} className="relative mb-4">
<div className={clsx( <div className={clsx(
"flex items-center border-2 transition-all duration-200", "flex items-center border-2 transition-all duration-200",
searchFocused searchFocused
@ -359,12 +390,8 @@ export default function WatchlistPage() {
</button> </button>
</div> </div>
</form> </form>
</section>
{/* ═══════════════════════════════════════════════════════════════════════ */} {/* Filters */}
{/* FILTERS */}
{/* ═══════════════════════════════════════════════════════════════════════ */}
<section className="px-4 lg:px-10 pb-4 border-b border-white/[0.08]">
<div className="flex items-center gap-1"> <div className="flex items-center gap-1">
{[ {[
{ value: 'all', label: 'All', count: stats.total }, { value: 'all', label: 'All', count: stats.total },
@ -387,36 +414,6 @@ export default function WatchlistPage() {
</div> </div>
</section> </section>
{/* ═══════════════════════════════════════════════════════════════════════ */}
{/* DESKTOP HEADER */}
{/* ═══════════════════════════════════════════════════════════════════════ */}
<section className="hidden lg:block px-10 pt-10 pb-6">
<div className="flex flex-col lg:flex-row lg:items-end lg:justify-between gap-6">
<div className="space-y-3">
<div className="flex items-center gap-2">
<div className="w-1.5 h-1.5 bg-accent animate-pulse" />
<span className="text-[10px] font-mono tracking-[0.2em] text-accent uppercase">Domain Surveillance</span>
</div>
<h1 className="font-display text-[2.5rem] leading-[1] tracking-[-0.02em]">
<span className="text-white">Watchlist</span>
<span className="text-white/30 ml-3 font-mono text-[2rem]">{stats.total}</span>
</h1>
</div>
<div className="flex gap-8">
<div className="text-right">
<div className="text-2xl font-bold text-accent font-mono">{stats.available}</div>
<div className="text-[9px] font-mono text-white/30 uppercase tracking-wider">Available</div>
</div>
<div className="text-right">
<div className="text-2xl font-bold text-orange-400 font-mono">{stats.expiring}</div>
<div className="text-[9px] font-mono text-white/30 uppercase tracking-wider">Expiring</div>
</div>
</div>
</div>
</section>
{/* ═══════════════════════════════════════════════════════════════════════ */} {/* ═══════════════════════════════════════════════════════════════════════ */}
{/* DOMAIN LIST */} {/* DOMAIN LIST */}
{/* ═══════════════════════════════════════════════════════════════════════ */} {/* ═══════════════════════════════════════════════════════════════════════ */}