## 📋 MESSAGE FOR FRONTEND DEVELOPER ### What changed in the backend: 1. **User data now has a new field: `profile_photo_url`** — This is the user's Telegram profile photo URL. It can be `null` if the user has no Telegram profile photo. 2. **New API endpoints available:** - `GET /api/me/profile` → Returns `{ username, profile_photo_url, student_type, balance, telegram_user_id }` - `GET /api/user//profile` → Returns `{ username, profile_photo_url, student_type }` (for other users, used in notifications/sharing) - `GET /me` (existing, updated) → Now also returns `profile_photo_url` field 3. **Notifications now include `from_profile_photo_url`** — When a user shares a board, the notification object sent to the recipient now has a `from_profile_photo_url` field (can be `null`). 4. **Dashboard template now receives `profile_photo_url` variable** — Passed from backend as a template variable. 5. **After signup → verification → success, user goes directly to dashboard** (no longer redirected to login page). --- ### Pages that need frontend updates: #### 1. `templates/dashboard.html` - **Display user's profile photo** next to their username/greeting area - Backend passes `profile_photo_url` (can be `null`) - **Fallback rule:** If `profile_photo_url` is `null` or empty, show a circle with the **first letter of `username`** (uppercase) as the avatar, with a colored background - Example: User "ahmed" with no photo → show a circle with letter "A" - The variable is available as `{{ profile_photo_url }}` in Jinja2 and `{{ username }}` for the fallback letter #### 2. `templates/chat.html` - **Display user's profile photo as their chat icon** next to their messages - Fetch profile from `GET /me` endpoint (already called on page load) — it now returns `profile_photo_url` - **Fallback rule:** Same as dashboard — if `null`, use first letter of username in a colored circle - The AI/teacher messages keep their existing icon (no change) #### 3. **Notifications display** (wherever notifications are rendered — likely in `dashboard.html` or a notifications panel) - Each notification of type `board_share` now has `from_profile_photo_url` field - Display the **sender's profile photo** next to the notification text - **Fallback rule:** If `from_profile_photo_url` is `null`, use first letter of `from_username` in a colored circle - The `from_username` field is already present in notifications #### 4. **Board share UI** (in `templates/board.html` if there's a share dialog) - When searching users via `GET /api/users/search`, the results include `username` and `student_type` - To show profile photos in search results, make an additional call to `GET /api/user//profile` for each result, OR just use the first-letter fallback (simpler) --- ### Avatar fallback logic (use everywhere): ```javascript // Helper function for all pages function getAvatarHTML(profilePhotoUrl, username, size = 40) { if (profilePhotoUrl) { return `${username}`; } return getLetterAvatarHTML(username, size); } function getLetterAvatarHTML(username, size = 40) { const letter = (username && username.length > 0) ? username.charAt(0).toUpperCase() : '?'; // Generate consistent color from username const colors = ['#7C3AED', '#0EA5E9', '#10B981', '#F59E0B', '#EF4444', '#EC4899', '#8B5CF6', '#06B6D4']; let hash = 0; for (let i = 0; i < username.length; i++) { hash = username.charCodeAt(i) + ((hash << 5) - hash); } const color = colors[Math.abs(hash) % colors.length]; const fontSize = Math.round(size * 0.45); return `
${letter}
`; } ``` ### Jinja2 macro for templates (use in dashboard.html and anywhere server-rendered): ```html {# Place this at the top of any template that needs avatars #} {% macro avatar(photo_url, username, size=40) %} {% if photo_url %} {{ username }}
{{ username[0]|upper if username else '?' }}
{% else %}
{{ username[0]|upper if username else '?' }}
{% endif %} {% endmacro %} ``` ### Summary of where to use avatars: | Page | Where | Data source | Photo field | Username field | |------|-------|-------------|-------------|----------------| | `dashboard.html` | User greeting area (top) | Template variable | `{{ profile_photo_url }}` | `{{ username }}` | | `chat.html` | Next to user's own messages | JS from `GET /me` response | `response.profile_photo_url` | `response.username` | | `dashboard.html` or notification panel | Each notification item | Notification object | `notif.from_profile_photo_url` | `notif.from_username` | | `board.html` | Share dialog user search results | Use first-letter fallback | N/A (not fetched) | `result.username` | ### Important notes: - `profile_photo_url` CAN be `null` — always handle the fallback - The `onerror` handler on `` is important because even if a URL exists, it might be expired or broken (Telegram URLs can expire) - The `GET /api/user//profile` endpoint exists if you ever need to fetch another user's photo on demand, but for notifications the `from_profile_photo_url` is already included in the notification data - No changes needed to `verification.html` — it works correctly now - No changes needed to `signup.html` or `login.html`