SideButton Marketing Website Knowledge Module
Portal Login — SideButton Marketing Website Knowledge Module
Login page for the SideButton Publisher Portal. Server-side rendered (SSR) page using the Astro Layout with Header and Footer. Features a centered email-only login form (no password field). On succes…
sidebutton install sidebutton.com What This Is
Login page for the SideButton Publisher Portal. Server-side rendered (SSR) page using the Astro Layout with Header and Footer. Features a centered email-only login form (no password field). On success, redirects to /portal or a server-specified redirect URL. If the user is already authenticated (Astro.locals.auth), the server redirects to /portal before rendering the page. Displays demo account emails in a hint section below the form.
URL Patterns
| Pattern | Description |
|---|---|
/login | Portal login page |
/login (authenticated) | Server-side redirect to /portal (page never renders) |
Page Structure
+--[Header: sticky banner]---------------------------+
| |
| [main#main-content — min-h-[80vh], centered] |
| [.w-full.max-w-sm] |
| |
| [.text-center.mb-8] |
| [Logo link → /] SideButton "S" SVG |
| H1: "Sign in to Publisher Portal" |
| P: "Enter your email to access your |
| dashboard" |
| |
| [form#login-form.space-y-4] |
| Label "Email address" + input#email |
| [#error-message] hidden by default |
| Button#submit-btn "Sign in" |
| |
| [.mt-8.pt-6.border-t] |
| Demo accounts hint (3 emails) |
| |
+--[Footer: 6-column grid]---------------------------+
Key Elements
| Element | Selector | Notes |
|---|---|---|
| Main content area | main#main-content | min-h-[80vh], flex centered, px-4 |
| Form container | .w-full.max-w-sm | Max width 24rem (384px) |
| Logo link | main a[href="/"] | SVG "S" logo in green #15C39A, links to homepage |
| Page heading | h1 | "Sign in to Publisher Portal", text-2xl font-bold |
| Subheading | h1 + p | "Enter your email to access your dashboard", text-text-secondary |
| Login form | form#login-form | space-y-4 layout, standard <form> with submit handler |
| Email label | label[for="email"] | "Email address", text-sm font-medium |
| Email input | input#email | type="email", name="email", required, placeholder "[email protected]", autocomplete="email" |
| Error message | #error-message | hidden class by default; red text on red-50 background |
| Submit button | button#submit-btn | "Sign in", type="submit", bg-primary green, full width |
| Demo hint | .mt-8.pt-6.border-t p | Lists 3 demo emails: [email protected], [email protected], [email protected] |
Data Model
| Field | Type | Description |
|---|---|---|
| string (email) | Publisher email address, trimmed before submission |
API Request (POST /api/auth/login)
| Field | Type | Description |
|---|---|---|
| string | From #email input, trimmed |
API Response (success)
| Field | Type | Description |
|---|---|---|
| redirect | string (optional) | URL to redirect to (default: /portal) |
API Response (failure)
| Field | Type | Description |
|---|---|---|
| error | string | Error message (e.g., "Login failed") |
States & Variations
| State | Trigger | Visual Indicator |
|---|---|---|
| Default | Page load | Empty email field with placeholder "[email protected]", "Sign in" button |
| Input focused | Click/tab into email | Ring-2 green outline (ring-primary/50), border changes to primary color |
| Submitting | Form submit | Button disabled, text changes to "Signing in..." |
| Validation error (browser) | Submit with empty email | Browser-native required validation popup (no custom JS) |
| Server error | API returns non-ok | #error-message unhidden, shows red error text on pink background |
| Network error | Fetch throws | #error-message shows "Network error. Please try again." |
| Success | API returns ok | window.location.href set to data.redirect or /portal |
| Already authenticated | Server detects Astro.locals.auth | Immediate 302 redirect to /portal (page never renders) |
Responsive Behavior
| Breakpoint | Behavior |
|---|---|
| All widths | Form is max-w-sm (384px), centered with px-4 padding |
| Mobile (<640px) | Full-width form within padding, stacked layout |
| Desktop (>640px) | Form centered in min-h-[80vh] area with Header above and Footer below |
Key Differences from /connect
| Aspect | /login | /connect |
|---|---|---|
| Purpose | Publisher Portal access | Chrome extension auth |
| Layout | Full site chrome (Header + Footer) | Standalone card, no chrome |
| Fields | Email only (no password) | Email + password |
| API endpoint | /api/auth/login | /api/mcp/login |
| On success | Redirect to /portal | Show success view, auto-close |
| Rendering | SSR (requires Astro server runtime) | Static HTML |
| Form element | <form> with submit event | <div> with click handler |
| Styling | Tailwind CSS utility classes | Inline <style> block |
Common Tasks
1. Verify login form renders
- Navigate to
/login - Confirm Header is visible at top
- Confirm
h1reads "Sign in to Publisher Portal" - Confirm subtitle reads "Enter your email to access your dashboard"
- Confirm
input#emailexists with placeholder "[email protected]" - Confirm
button#submit-btnreads "Sign in" - Confirm Footer is visible at bottom
2. Login with valid credentials
- Click
input#email - Type
[email protected] - Click
button#submit-btn(or press Enter) - Verify button text changes to "Signing in..."
- Verify redirect to
/portalpage
3. Verify browser-native validation
- Leave email empty
- Click
button#submit-btn - Verify browser shows native "Please fill out this field" tooltip (from
requiredattribute) - Type
notanemail(no @ symbol) - Click
button#submit-btn - Verify browser shows native email format validation message
4. Verify server error handling
- Type an unregistered email (e.g.,
[email protected]) - Click
button#submit-btn - Verify
#error-messagebecomes visible with error text - Verify button re-enables with text "Sign in"
5. Verify demo accounts hint
- Scroll below the form
- Verify hint text lists 3 emails:
[email protected],[email protected],[email protected] - Verify hint is separated by a top border
6. Verify logo link
- Click the SideButton "S" logo above the heading
- Verify navigation to
/(homepage)
Tips
- This page is SSR-only (
export const prerender = false) -- it will not work on a static build; requires the Astro server runtime - No password field -- the login is email-only; authentication logic is server-side
- The form uses a standard
<form>element withsubmitevent, so browser-native validation (required,type="email") applies before JS runs - The
finallyblock always re-enables the button and resets text to "Sign in", even after errors - Server-side auth check redirects to
/portalbefore page render -- you cannot see the login page while authenticated - The submit handler uses
e.preventDefault()to stop native form submission and handle it viafetch - Redirect URL comes from server response (
data.redirect) with/portalas fallback - Tailwind CSS classes are used throughout -- unlike
/connectwhich uses inline styles
Gotchas
- SSR requirement: Accessing
/loginon a statically built site returns a blank page or error -- the page requiresprerender = falseand a running Astro server - No password field: Unlike
/connect, this form has no password input -- do not look for or try to fill a password field - Browser validation fires first: The
requiredattribute oninput#emailcauses browser-native validation before the JS submit handler runs; automation tools that bypass form validation may skip this check - Auth redirect is server-side: The
Astro.locals.authcheck andAstro.redirect('/portal')happen during SSR -- there is no client-side redirect for already-authenticated users; the page simply never renders - Error message reuse: The same
#error-messagediv handles both server errors and network errors; its content is overwritten each time -- there is no separate element for different error types - Button state always resets: The
finallyblock re-enables the button even on success, butwindow.location.hrefassignment navigates away before the user sees it; in slow-redirect scenarios the button may briefly flash back to "Sign in"