v2: In-app support chat with Telegram notifications (REVIEW — not deployed)
Backend: - New models: SupportThread, SupportMessage (models/support.py) - Support router: user thread/messages, admin threads/reply, Telegram outbound - Context auto-attached: active program, points, gate status, last workout - Rate limited: 10 messages/user/day - Admin auth: username == 'scot' check - Telegram: fire-and-forget sendMessage via @AureusGoldBot, never blocks - config.py: added telegram_bot_token, telegram_chat_id Frontend: - Support.jsx: chat-style thread, send messages, confirmation, auto-scroll - SupportAdmin.jsx: thread list with unread badges, thread detail with context sidebar, reply - App.jsx: floating '?' help button with unread badge (polls every 60s), routes - api.js: support endpoints (user + admin) Config: - docker-compose.yml: TELEGRAM_BOT_TOKEN and TELEGRAM_CHAT_ID env vars NOT DEPLOYED — requires Telegram env vars in Coolify
This commit is contained in:
parent
42632b1b50
commit
10f13a9f62
10 changed files with 988 additions and 4 deletions
|
|
@ -64,12 +64,12 @@ export const api = {
|
|||
createReward: (data) => request('/rewards', { method: 'POST', body: JSON.stringify(data) }),
|
||||
redeemReward: (id, date) => request(`/rewards/${id}/redeem`, { method: 'POST', body: JSON.stringify({ date }) }),
|
||||
|
||||
// Programs (v1 — existing)
|
||||
// Programs (v1)
|
||||
listPrograms: () => request('/programs'),
|
||||
createProgram: (data) => request('/programs', { method: 'POST', body: JSON.stringify(data) }),
|
||||
getProgram: (id) => request(`/programs/${id}`),
|
||||
|
||||
// Program Catalog (v2 — new)
|
||||
// Program Catalog (v2)
|
||||
searchCatalog: (q) => request(`/programs/catalog${q ? `?q=${encodeURIComponent(q)}` : ''}`),
|
||||
getCatalogProgram: (id) => request(`/programs/catalog/${id}`),
|
||||
researchProgram: (name) =>
|
||||
|
|
@ -79,7 +79,7 @@ export const api = {
|
|||
method: 'POST', body: JSON.stringify({ start_date: startDate }),
|
||||
}),
|
||||
|
||||
// Program Tracking (v2 — new)
|
||||
// Program Tracking (v2)
|
||||
getProgramSchedule: (id) => request(`/programs/${id}/schedule`),
|
||||
getWorkoutDetail: (progId, workoutId) => request(`/programs/${progId}/workout/${workoutId}`),
|
||||
completeWorkout: (progId, workoutId, data) =>
|
||||
|
|
@ -88,6 +88,20 @@ export const api = {
|
|||
}),
|
||||
getProgramProgress: (id) => request(`/programs/${id}/progress`),
|
||||
|
||||
// Support (user)
|
||||
getThread: () => request('/support/thread'),
|
||||
sendSupportMessage: (body) =>
|
||||
request('/support/messages', { method: 'POST', body: JSON.stringify({ body }) }),
|
||||
getUnreadCount: () => request('/support/unread'),
|
||||
|
||||
// Support (admin)
|
||||
listSupportThreads: () => request('/support/admin/threads'),
|
||||
getAdminThread: (threadId) => request(`/support/admin/threads/${threadId}`),
|
||||
replySupportThread: (threadId, body) =>
|
||||
request(`/support/admin/threads/${threadId}/reply`, {
|
||||
method: 'POST', body: JSON.stringify({ body }),
|
||||
}),
|
||||
|
||||
// Integrations
|
||||
integrationStatus: () => request('/integrations'),
|
||||
stravaAuth: () => request('/integrations/strava/auth'),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue