Skip to content

davidjosesao/aether-frontend

Repository files navigation

Aether Frontend — Design Handoff

This is the redesigned marketing and account site for the Aether client, built on top of the frontend design copy you provided. All pages have been rebuilt to match the pixel/terminal aesthetic from the design handoff, and the integration stubs are ready for you to wire up.


What was done

New design system

  • Font: MaruMinya pixel bitmap font (/public/fonts/x12y12pxMaruMinya.ttf) across all pages.
  • Palette: Near-black blue-tinted background (#0a0b10), single cyan accent (#22d3ee), periwinkle logo (#A0B4FA). All tokens in app/globals.css :root.
  • Dark/light theme: data-theme attribute on <html>, bootstrapped from localStorage before first paint to avoid flash. Toggle in the nav.

Pages rebuilt

Page File
Landing (hero, about, features, pricing) app/page.tsx
Login / sign-up app/login/page.tsx + components/login-shell.tsx
Terms of service app/tos/page.tsx (original markup preserved, new shell)
Discord verify app/discord/verify/page.tsx
Dashboard shell + all sub-pages app/dashboard/**
Admin shell + all sub-pages app/admin/**

New components

Component What it does
components/starfield.tsx Canvas animated starfield — mounts once in root layout, full-doc-height stars, hover repel, click shockwaves, hyperspace streaks
components/scroll-reveal.tsx IntersectionObserver that adds .up to .reveal elements for scroll-in animations
components/site-nav-links.tsx Client nav links — in-page anchors with hyperspace on the landing page, cross-page links on login
components/design-page-nav.tsx Dev-only bottom-left page switcher. Remove this component and its usage in app/layout.tsx before shipping.

Components preserved from your codebase

All dashboard/admin UI components (workspace-shell, license-manager, checkout-form, admin-*, etc.) are unchanged. Only the shell around them was redesigned.


What needs wiring

1. Supabase — authentication

lib/website-auth.ts and lib/supabase/browser.ts are currently stubs that return mock data. Replace them with your real @supabase/ssr client.

lib/supabase/browser.ts — replace the mock with:

import { createBrowserClient } from "@supabase/ssr";
export function createBrowserSupabaseClient() {
  return createBrowserClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY!
  );
}

lib/website-auth.ts — replace mocks with real session reads using your server client (cookies-based). Example pattern:

import { createServerClient } from "@supabase/ssr";
import { cookies } from "next/headers";

export async function getWebsiteUser() {
  const cookieStore = await cookies();
  const supabase = createServerClient(..., { cookies: { getAll: () => cookieStore.getAll() } });
  const { data: { user } } = await supabase.auth.getUser();
  return user ? { id: user.id, email: user.email ?? null } : null;
}

export async function requireWebsiteUser() {
  const user = await getWebsiteUser();
  if (!user) redirect("/login");
  return user;
}

2. Auth API routes

app/api/auth/login/route.ts, signup/route.ts, magiclink/route.ts, and recovery/route.ts are stub handlers that accept requests and return { success: true }. Wire your Supabase calls in the // TODO spots in each file.

The login-shell.tsx form posts to these routes and expects:

  • Signup: { success: true, needsEmailVerification?: boolean } or { success: false, error: string } (non-2xx)
  • Login / magic link / recovery: { success: true } or { success: false, error: string } (non-2xx)

3. Cloudflare Turnstile (CAPTCHA)

Set NEXT_PUBLIC_TURNSTILE_SITE_KEY in your env. The login form automatically shows the Turnstile widget when this key is present. The turnstileToken is already passed to all four auth API routes — verify it server-side using TURNSTILE_SECRET_KEY before processing.

// Verify in your API route before calling Supabase:
const verifyRes = await fetch("https://challenges.cloudflare.com/turnstile/v0/siteverify", {
  method: "POST",
  body: new URLSearchParams({ secret: process.env.TURNSTILE_SECRET_KEY!, response: turnstileToken }),
});
const { success } = await verifyRes.json();
if (!success) return NextResponse.json({ success: false, error: "Captcha failed." }, { status: 400 });

4. Stripe pricing

lib/stripe-catalog.ts returns hardcoded mock prices. Replace each function with a real stripe.prices.retrieve(process.env.STRIPE_PRICE_*) call. Price IDs are in .env.example.

5. Admin access

Admin pages (/admin/*) are protected by lib/admin.ts. Set ADMIN_EMAILS in your env to a comma-separated list of admin email addresses. Anyone not on the list is redirected to /dashboard. See lib/admin.ts for the full logic — swap the email check for a role check if you use Supabase roles.

6. Other integrations

The following lib files are stubs with the right function signatures — drop in your real implementations:

  • lib/discord.ts — Discord role sync and verification
  • lib/licenses.ts — license types only (no server logic)
  • lib/stripe-fulfillment.ts — webhook fulfillment
  • lib/oxapay.ts — OxaPay crypto checkout
  • lib/feature-payload-store.ts — feature binary upload/management
  • lib/loader-payload-store.ts — loader JAR upload/management
  • lib/github-direct-upload.ts — GitHub release upload helper
  • lib/supabase-direct-upload.ts — Supabase Storage upload helper
  • lib/minecraft.ts — Minecraft UUID/username lookup

Running locally

cp .env.example .env.local
# Fill in .env.local with real or test values
npm install
npm run dev
# → http://localhost:3000

Without real env values the site still runs — auth routes return mock successes, prices show placeholder amounts, and the dashboard shows mock data.


Before shipping

  • Remove <DesignPageNav /> from app/layout.tsx and delete components/design-page-nav.tsx
  • Remove app/globals-design.css and its import in app/layout.tsx
  • Remove lib/mock-data.ts after all dashboard pages are wired to real data
  • Verify the MaruMinya font license (/public/fonts/x12y12pxMaruMinya.ttf) — confirm permitted for web use or swap to a licensed alternative
  • Set ADMIN_EMAILS before deploying admin routes
  • Add Turnstile secret verification to all four auth API routes
  • Set up Supabase auth callback route (/auth/callback) for email confirmation and magic link flows

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors