# TenderRadar Navigation System & Shared Layout Complete implementation guide for consistent navigation, authentication, and styling across all TenderRadar pages. ## 📁 File Structure ``` /var/www/tenderradar/ ├── auth.js # Shared auth utilities ├── app.css # Shared app styles ├── index.html # Landing page (unchanged) ├── login.html # Login page ├── signup.html # Sign up page ├── dashboard.html # Dashboard page ├── profile.html # User profile page ├── alerts.html # Alerts page ├── tenders.html # Tenders page (optional) ├── styles.css # Landing page styles (unchanged) ├── script.js # Landing page script (unchanged) └── components/ ├── nav.js # Navigation component └── footer.js # Footer component ``` ## 🚀 Quick Start ### 1. Add Auth Module to All App Pages Add this to the `` of every app page (dashboard, profile, alerts, etc.): ```html ``` ### 2. Add Navigation & Footer Components Add these before the closing `` tag on every app page: ```html ``` ### 3. Include App Styles Add this to the `` of every app page: ```html ``` ### 4. Protect Pages with Auth Check Add this immediately after loading auth.js in your page JavaScript: ```javascript // Require authentication on this page requireAuth(); ``` --- ## 📋 Complete Example: dashboard.html ```html Dashboard | TenderRadar
``` --- ## 🔐 Authentication API Reference ### `getToken()` Retrieves the stored JWT token. ```javascript const token = getToken(); if (token) { console.log('User is authenticated'); } ``` ### `setToken(token)` Stores a JWT token in localStorage. ```javascript // Typically done after login setToken(response.token); ``` ### `clearToken()` Removes the JWT token from localStorage. ```javascript clearToken(); ``` ### `isAuthenticated()` Checks if user is currently authenticated. ```javascript if (isAuthenticated()) { // Show app content } else { // Redirect to login } ``` ### `getUserInfo()` Decodes and returns the JWT payload (user info). ```javascript const user = getUserInfo(); console.log(user.email); // User's email console.log(user.id); // User ID console.log(user.iat); // Issued at console.log(user.exp); // Expiration time ``` ### `requireAuth()` Redirects to login page if not authenticated. Use this in page initialization. ```javascript // At top of page script requireAuth(); ``` ### `logout()` Clears token and redirects to login page. ```javascript // Called when user clicks logout button logout(); ``` ### `fetchWithAuth(url, options)` Wrapper around fetch() that automatically adds Authorization header. ```javascript // GET request with auth const response = await fetchWithAuth('/api/tenders'); const data = await response.json(); // POST request with auth const response = await fetchWithAuth('/api/profile', { method: 'POST', body: JSON.stringify({ name: 'John' }) }); ``` --- ## 🎨 Navigation Component Features The `NavBar` component automatically: ✅ Injects a sticky navbar at the top of the page ✅ Shows different content based on auth state ✅ Displays user email + avatar for authenticated users ✅ Highlights the current active page ✅ Handles logout with token clearing ✅ Mobile-responsive hamburger menu ✅ Responsive user dropdown menu ### Navigation Links (Authenticated) - **Dashboard** → `/dashboard.html` - **Tenders** → `/tenders.html` - **Alerts** → `/alerts.html` - **Profile** → `/profile.html` ### Navigation Links (Unauthenticated) - **Login** → `/login.html` - **Sign Up** → `/signup.html` --- ## 🎨 Styling System ### Color Variables ```css --primary: #1e40af; /* Deep Blue */ --primary-dark: #1e3a8a; /* Darker Blue */ --primary-light: #3b82f6; /* Light Blue */ --accent: #f59e0b; /* Orange */ --success: #10b981; /* Green */ --danger: #ef4444; /* Red */ --warning: #f59e0b; /* Orange */ --info: #3b82f6; /* Blue */ ``` ### Component Classes #### Cards ```html

Tender Details

...
``` #### Buttons ```html ``` #### Badges & Tags ```html Active Approved Pending Rejected
Python ×
``` #### Alerts & Notifications ```html
Success!
Your profile has been updated.
!
Error
Something went wrong. Please try again.
``` #### Tables ```html
Tender ID Title Status Action
TR-001 Ministry Website Redesign Open
``` #### Forms ```html
We'll never share your email.
Password must be at least 8 characters.
``` #### Grids & Layouts ```html
Column 1
Column 2
Column 3 (wraps to new row)
Stat 1
Stat 2
Stat 3
``` #### Loading States ```html
Loading tenders...
``` #### Empty States ```html

No tenders yet

Create your first alert to start receiving tender matches.

``` --- ## 📱 Responsive Design All components are fully responsive with mobile-first design: - **Desktop**: Full navigation with all menu items visible - **Tablet** (768px): Optimized spacing and layouts - **Mobile** (480px): Hamburger menu, single-column layouts, optimized touch targets ### Mobile Navigation On mobile, the navbar automatically switches to a hamburger menu that can be toggled to show/hide navigation items. ### Form Inputs on Mobile All inputs use `font-size: 1rem` on mobile to prevent iOS auto-zoom. --- ## 🔗 Integration with Existing Pages ### Landing Page (index.html) - **No Changes Needed** The landing page uses `styles.css` and works independently. No auth required. ### Login Page (login.html) ```javascript // On successful login, store token: setToken(response.token); // Then redirect: window.location.href = '/dashboard.html'; ``` ### Sign Up Page (signup.html) ```javascript // After successful registration: setToken(response.token); // Then redirect: window.location.href = '/dashboard.html'; ``` ### Protected Pages (dashboard.html, profile.html, alerts.html) All must: 1. Load `auth.js` first 2. Load `app.css` for styling 3. Load navigation and footer components 4. Call `requireAuth()` to protect the page 5. Use `fetchWithAuth()` for API calls --- ## 🛠️ Utility Classes ### Spacing ```html
...
...
...
``` ### Text ```html
Centered text
Right-aligned text
Blue text
Green text
Text that truncates...
Text limited to 2 lines...
``` ### Display ```html
Visible element
50% opacity
75% opacity
``` --- ## 📋 Checklist for Page Implementation - [ ] Add `` to `` - [ ] Add `` to `` - [ ] Add navigation component script before `` - [ ] Add footer component script before `` - [ ] Call `requireAuth()` in page script (for protected pages) - [ ] Wrap content in `
` - [ ] Use `fetchWithAuth()` for all API calls - [ ] Test mobile responsiveness - [ ] Test logout functionality - [ ] Verify navigation highlights correct active page --- ## 🐛 Troubleshooting ### Navigation not showing? - Check that `auth.js` is loaded before `nav.js` - Verify `nav.js` exists at `/components/nav.js` - Check browser console for errors ### Styles not applying? - Ensure `app.css` is loaded after landing `styles.css` - Clear browser cache - Check file permissions on server ### Auth checks not working? - Verify `auth.js` is loaded first - Check localStorage for `tenderradar_token` - Look for JS errors in browser console ### API calls failing? - Verify JWT token is valid and not expired - Use `fetchWithAuth()` instead of plain `fetch()` - Check server CORS settings if cross-domain --- ## 📚 Additional Resources - **Brand Colors**: Primary #1e40af, Accent #f59e0b - **Font Family**: Inter (from Google Fonts) - **Layout Width**: Max 1400px container - **Shadow System**: sm, md, lg, xl variants - **Responsive Breakpoints**: 768px (tablet), 480px (mobile) --- **Created**: 2026-02-14 **Last Updated**: 2026-02-14