182 lines
4.2 KiB
Markdown
182 lines
4.2 KiB
Markdown
|
|
# TenderRadar Navigation System - Quick Reference
|
||
|
|
|
||
|
|
## 📋 File Locations
|
||
|
|
|
||
|
|
```
|
||
|
|
/auth.js - Shared auth utilities
|
||
|
|
/app.css - Shared app styles (27 KB)
|
||
|
|
/components/nav.js - Navigation component
|
||
|
|
/components/footer.js - Footer component
|
||
|
|
```
|
||
|
|
|
||
|
|
## 🚀 Minimal Setup (Copy & Paste)
|
||
|
|
|
||
|
|
### Step 1: Add to HTML Head
|
||
|
|
```html
|
||
|
|
<link rel="stylesheet" href="/app.css">
|
||
|
|
<script src="/auth.js"></script>
|
||
|
|
```
|
||
|
|
|
||
|
|
### Step 2: Add to HTML Body (before closing tag)
|
||
|
|
```html
|
||
|
|
<script src="/components/nav.js"></script>
|
||
|
|
<script src="/components/footer.js"></script>
|
||
|
|
```
|
||
|
|
|
||
|
|
### Step 3: Protect Page (in your page script)
|
||
|
|
```javascript
|
||
|
|
requireAuth(); // Redirects to login if not authenticated
|
||
|
|
```
|
||
|
|
|
||
|
|
### Step 4: Make API Calls
|
||
|
|
```javascript
|
||
|
|
// Instead of fetch():
|
||
|
|
const response = await fetchWithAuth('/api/tenders');
|
||
|
|
const data = await response.json();
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🔐 Auth Functions (Quick Lookup)
|
||
|
|
|
||
|
|
| Function | Purpose | Example |
|
||
|
|
|----------|---------|---------|
|
||
|
|
| `getToken()` | Get JWT | `const t = getToken();` |
|
||
|
|
| `setToken(t)` | Store JWT | `setToken(response.token);` |
|
||
|
|
| `clearToken()` | Remove JWT | `clearToken();` |
|
||
|
|
| `isAuthenticated()` | Check auth | `if (isAuthenticated()) {...}` |
|
||
|
|
| `getUserInfo()` | Get user data | `const u = getUserInfo(); u.email` |
|
||
|
|
| `requireAuth()` | Protect page | `requireAuth();` |
|
||
|
|
| `logout()` | Sign out | `logout();` |
|
||
|
|
| `fetchWithAuth(url)` | API with auth | `await fetchWithAuth('/api/...')` |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🎨 Most Used Component Classes
|
||
|
|
|
||
|
|
### Buttons
|
||
|
|
```html
|
||
|
|
<button class="btn btn-primary">Primary</button>
|
||
|
|
<button class="btn btn-secondary">Secondary</button>
|
||
|
|
<button class="btn btn-danger">Danger</button>
|
||
|
|
<button class="btn btn-lg">Large</button>
|
||
|
|
<button class="btn btn-block">Full Width</button>
|
||
|
|
```
|
||
|
|
|
||
|
|
### Cards
|
||
|
|
```html
|
||
|
|
<div class="card">
|
||
|
|
<div class="card-header"><h2 class="card-title">Title</h2></div>
|
||
|
|
<div class="card-content">Content</div>
|
||
|
|
<div class="card-footer">Footer</div>
|
||
|
|
</div>
|
||
|
|
```
|
||
|
|
|
||
|
|
### Badges & Tags
|
||
|
|
```html
|
||
|
|
<span class="badge badge-success">Success</span>
|
||
|
|
<div class="tag">Label</div>
|
||
|
|
```
|
||
|
|
|
||
|
|
### Alerts
|
||
|
|
```html
|
||
|
|
<div class="alert alert-success">Success message</div>
|
||
|
|
<div class="alert alert-danger">Error message</div>
|
||
|
|
```
|
||
|
|
|
||
|
|
### Forms
|
||
|
|
```html
|
||
|
|
<div class="form-group">
|
||
|
|
<label>Email</label>
|
||
|
|
<input type="email" required>
|
||
|
|
</div>
|
||
|
|
<div class="form-row form-row-2">
|
||
|
|
<div class="form-group"><label>First</label><input></div>
|
||
|
|
<div class="form-group"><label>Last</label><input></div>
|
||
|
|
</div>
|
||
|
|
```
|
||
|
|
|
||
|
|
### Tables
|
||
|
|
```html
|
||
|
|
<div class="table-wrapper">
|
||
|
|
<table>...</table>
|
||
|
|
</div>
|
||
|
|
```
|
||
|
|
|
||
|
|
### Grids
|
||
|
|
```html
|
||
|
|
<div class="grid grid-2">...</div>
|
||
|
|
<div class="grid grid-cols-3">...</div>
|
||
|
|
```
|
||
|
|
|
||
|
|
### Loading
|
||
|
|
```html
|
||
|
|
<div class="spinner"></div>
|
||
|
|
<div class="loading"><div class="spinner"></div>Loading...</div>
|
||
|
|
```
|
||
|
|
|
||
|
|
### Empty State
|
||
|
|
```html
|
||
|
|
<div class="empty-state">
|
||
|
|
<div class="empty-state-icon">🗂️</div>
|
||
|
|
<h3 class="empty-state-title">No items</h3>
|
||
|
|
<p class="empty-state-desc">Description</p>
|
||
|
|
</div>
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🎨 Colors
|
||
|
|
|
||
|
|
| Name | Value | Use |
|
||
|
|
|------|-------|-----|
|
||
|
|
| Primary | #1e40af (blue) | Main actions, highlights |
|
||
|
|
| Accent | #f59e0b (orange) | Secondary actions |
|
||
|
|
| Success | #10b981 (green) | Positive feedback |
|
||
|
|
| Danger | #ef4444 (red) | Errors, destructive |
|
||
|
|
| Warning | #f59e0b (orange) | Warnings |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📱 Responsive Breakpoints
|
||
|
|
|
||
|
|
- **Desktop**: 1200px+ (full layout)
|
||
|
|
- **Tablet**: 768px-1199px (optimized spacing)
|
||
|
|
- **Mobile**: Below 768px (hamburger menu, single column)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## ✅ Implementation Checklist
|
||
|
|
|
||
|
|
For each new page (dashboard, profile, alerts, etc.):
|
||
|
|
|
||
|
|
- [ ] Load `/auth.js` in `<head>`
|
||
|
|
- [ ] Load `/app.css` in `<head>`
|
||
|
|
- [ ] Load `/components/nav.js` before `</body>`
|
||
|
|
- [ ] Load `/components/footer.js` before `</body>`
|
||
|
|
- [ ] Call `requireAuth()` in page script
|
||
|
|
- [ ] Use `fetchWithAuth()` for API calls
|
||
|
|
- [ ] Wrap content in `<main class="app-container">`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🔗 Navigation Structure
|
||
|
|
|
||
|
|
**Authenticated Users:**
|
||
|
|
- Dashboard → `/dashboard.html`
|
||
|
|
- Tenders → `/tenders.html`
|
||
|
|
- Alerts → `/alerts.html`
|
||
|
|
- Profile → `/profile.html`
|
||
|
|
- [User Email] + Logout
|
||
|
|
|
||
|
|
**Unauthenticated Users:**
|
||
|
|
- Login → `/login.html`
|
||
|
|
- Sign Up → `/signup.html`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📚 Full Documentation
|
||
|
|
|
||
|
|
For complete details, see: `/var/www/tenderradar/IMPLEMENTATION_GUIDE.md`
|
||
|
|
|