{program?.name || 'Laddar...'}
-{program?.description}
-diff --git a/frontend/src/App.css b/frontend/src/App.css index 32b7e78..4eee35c 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -375,3 +375,401 @@ padding-bottom: calc(1rem + env(safe-area-inset-bottom)); } } + +/* ============================================ + DASHBOARD STYLES + ============================================ */ + +.dashboard { + min-height: 100vh; + background: var(--bg); +} + +.dashboard.loading { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 1rem; +} + +/* Dashboard Header */ +.dashboard-header { + background: var(--bg-secondary); + padding: 1rem 1.25rem; + border-bottom: 1px solid var(--border); + position: sticky; + top: 0; + z-index: 100; +} + +.header-top { + display: flex; + justify-content: space-between; + align-items: center; +} + +.header-top h1 { + font-size: 1.5rem; + font-weight: 700; +} + +.nav-menu { + display: flex; + gap: 0.25rem; +} + +.nav-btn { + background: transparent; + border: none; + color: var(--text-muted); + padding: 0.5rem 0.75rem; + border-radius: 8px; + font-size: 0.85rem; + cursor: pointer; + transition: all 0.2s; +} + +.nav-btn:hover, +.nav-btn.active { + background: var(--bg); + color: var(--text); +} + +.nav-btn.logout { + color: var(--text-muted); +} + +/* Dashboard Main */ +.dashboard-main { + padding: 1rem; + display: flex; + flex-direction: column; + gap: 1.5rem; + max-width: 600px; + margin: 0 auto; +} + +/* Coach Greeting */ +.coach-greeting { + display: flex; + gap: 1rem; + padding: 1rem; + background: linear-gradient(135deg, var(--accent) 0%, #6366f1 100%); + border-radius: 16px; + color: white; +} + +.coach-avatar { + font-size: 2.5rem; + width: 60px; + height: 60px; + background: rgba(255,255,255,0.2); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; +} + +.coach-message { + display: flex; + align-items: center; +} + +.coach-message p { + font-size: 1.1rem; + font-weight: 500; + line-height: 1.4; +} + +/* Week Calendar */ +.week-calendar { + background: var(--bg-secondary); + border-radius: 16px; + padding: 1rem; + border: 1px solid var(--border); +} + +.calendar-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 1rem; +} + +.calendar-title { + font-weight: 600; + text-transform: capitalize; +} + +.calendar-nav { + background: var(--bg); + border: 1px solid var(--border); + width: 32px; + height: 32px; + border-radius: 8px; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + color: var(--text); + transition: all 0.2s; +} + +.calendar-nav:hover { + background: var(--accent); + color: white; + border-color: var(--accent); +} + +.calendar-days { + display: grid; + grid-template-columns: repeat(7, 1fr); + gap: 0.5rem; +} + +.calendar-day { + display: flex; + flex-direction: column; + align-items: center; + padding: 0.5rem; + border-radius: 12px; + cursor: pointer; + transition: all 0.2s; + position: relative; +} + +.calendar-day:hover { + background: var(--bg); +} + +.calendar-day.today { + background: var(--accent); + color: white; +} + +.calendar-day.has-workout .day-dot { + color: var(--success); +} + +.calendar-day.today .day-dot { + color: white; +} + +.day-name { + font-size: 0.7rem; + text-transform: uppercase; + color: var(--text-muted); + margin-bottom: 0.25rem; +} + +.calendar-day.today .day-name { + color: rgba(255,255,255,0.8); +} + +.day-date { + font-size: 1rem; + font-weight: 600; +} + +.day-dot { + font-size: 0.5rem; + margin-top: 0.25rem; +} + +/* Today's Workout */ +.todays-workout { + display: flex; + flex-direction: column; + gap: 1rem; +} + +.todays-workout h2 { + font-size: 1.1rem; + font-weight: 600; +} + +.workout-card { + background: var(--bg-secondary); + border-radius: 16px; + padding: 1.25rem; + border: 1px solid var(--border); + cursor: pointer; + transition: all 0.2s; +} + +.workout-card:hover { + border-color: var(--accent); + transform: translateY(-2px); +} + +.workout-card-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 1rem; +} + +.workout-card-header h3 { + font-size: 1.2rem; + font-weight: 600; +} + +.workout-duration { + font-size: 0.85rem; + color: var(--text-muted); +} + +.workout-exercises { + display: flex; + flex-direction: column; + gap: 0.5rem; + margin-bottom: 1rem; +} + +.exercise-preview { + display: flex; + justify-content: space-between; + padding: 0.5rem 0; + border-bottom: 1px solid var(--border); +} + +.exercise-preview:last-child { + border-bottom: none; +} + +.exercise-name { + font-weight: 500; +} + +.exercise-sets { + color: var(--text-muted); + font-size: 0.9rem; +} + +.start-workout-btn { + width: 100%; + background: var(--accent); + color: white; + border: none; + padding: 1rem; + border-radius: 12px; + font-size: 1rem; + font-weight: 600; + cursor: pointer; + transition: all 0.2s; +} + +.start-workout-btn:hover { + background: var(--accent-hover); + transform: scale(1.02); +} + +/* Rest Day Card */ +.rest-day-card { + background: var(--bg-secondary); + border-radius: 16px; + padding: 2rem; + border: 1px solid var(--border); + text-align: center; +} + +.rest-icon { + font-size: 3rem; + margin-bottom: 1rem; +} + +.rest-day-card h3 { + font-size: 1.2rem; + margin-bottom: 0.5rem; +} + +.rest-day-card p { + color: var(--text-muted); + margin-bottom: 1rem; +} + +.rest-tips { + display: flex; + justify-content: center; + gap: 1rem; +} + +.rest-tips span { + background: var(--bg); + padding: 0.5rem 0.75rem; + border-radius: 20px; + font-size: 0.85rem; +} + +/* Quick Stats */ +.quick-stats { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 0.75rem; +} + +.stat-card { + background: var(--bg-secondary); + border-radius: 12px; + padding: 1rem; + text-align: center; + border: 1px solid var(--border); +} + +.stat-value { + display: block; + font-size: 1.5rem; + font-weight: 700; + color: var(--accent); +} + +.stat-label { + font-size: 0.75rem; + color: var(--text-muted); + text-transform: uppercase; +} + +/* Upcoming Workouts */ +.upcoming-workouts h2 { + font-size: 1.1rem; + font-weight: 600; + margin-bottom: 0.75rem; +} + +.upcoming-list { + display: flex; + flex-direction: column; + gap: 0.5rem; +} + +.upcoming-item { + display: flex; + align-items: center; + gap: 1rem; + background: var(--bg-secondary); + padding: 1rem; + border-radius: 12px; + border: 1px solid var(--border); + cursor: pointer; + transition: all 0.2s; +} + +.upcoming-item:hover { + border-color: var(--accent); +} + +.upcoming-day { + font-weight: 600; + width: 40px; + color: var(--accent); +} + +.upcoming-name { + flex: 1; +} + +.upcoming-arrow { + color: var(--text-muted); +} diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 64f62cc..a7f01db 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -1,34 +1,30 @@ import { useState, useEffect } from 'react' import { useAuth } from './context/AuthContext' +import Dashboard from './pages/Dashboard' import './App.css' const API_URL = '/api' function App() { const { user, logout } = useAuth() - const [view, setView] = useState('program') + const [view, setView] = useState('dashboard') const [program, setProgram] = useState(null) const [selectedDay, setSelectedDay] = useState(null) const [currentWeek, setCurrentWeek] = useState(1) const [logs, setLogs] = useState({}) - const [loading, setLoading] = useState(true) + const [loading, setLoading] = useState(false) const userId = user?.id || 1 const today = new Date().toISOString().split('T')[0] - useEffect(() => { - fetchProgram() - }, []) - const fetchProgram = async () => { + if (program) return // Already loaded try { const res = await fetch(`${API_URL}/programs/1`) const data = await res.json() setProgram(data) - setLoading(false) } catch (err) { console.error('Failed to fetch program:', err) - setLoading(false) } } @@ -90,21 +86,19 @@ function App() { } } - const startWorkout = (day) => { + const startWorkout = async (day) => { + await fetchProgram() // Ensure program is loaded setSelectedDay(day) setView('workout') fetchLogs(day.id) } - if (loading) { - return ( -
Laddar program...
-{program?.description}
-Laddar...
Laddar...
+{getCoachGreeting(user, todayWorkout)}
+Inga pass schemalagda. Fokusera pÄ ÄterhÀmtning!
+