feat: Enhance navigation and dashboard with goals integration and UI improvements
This commit is contained in:
parent
952cb90973
commit
6e952f9277
|
|
@ -41,15 +41,46 @@ body { font-family: var(--font); background: var(--bg); color: var(--text1); -we
|
|||
.bottom-nav {
|
||||
position: fixed; bottom: 0; left: 50%; transform: translateX(-50%);
|
||||
width: 100%; max-width: 600px;
|
||||
height: var(--nav-h); display: flex; align-items: stretch;
|
||||
background: var(--surface); border-top: 1px solid var(--border);
|
||||
height: var(--nav-h);
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
background: var(--surface);
|
||||
border-top: 1px solid var(--border);
|
||||
z-index: 20;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
justify-content: flex-start;
|
||||
gap: 2px;
|
||||
padding: 0 6px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.bottom-nav::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
.nav-item {
|
||||
flex: 1; display: flex; flex-direction: column; align-items: center;
|
||||
justify-content: center; gap: 3px; color: var(--text3);
|
||||
text-decoration: none; font-size: 10px; font-weight: 500;
|
||||
transition: color 0.15s; padding-bottom: env(safe-area-inset-bottom, 0);
|
||||
flex: 0 0 auto;
|
||||
min-width: 56px;
|
||||
max-width: 96px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 3px;
|
||||
color: var(--text3);
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
transition: color 0.15s;
|
||||
padding: 0 4px calc(4px + env(safe-area-inset-bottom, 0));
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.nav-item span {
|
||||
font-size: 10px;
|
||||
line-height: 1.15;
|
||||
text-align: center;
|
||||
max-width: 100%;
|
||||
}
|
||||
.nav-item.active { color: var(--accent); }
|
||||
.nav-item svg { flex-shrink: 0; }
|
||||
|
|
@ -256,11 +287,15 @@ body { font-family: var(--font); background: var(--bg); color: var(--text1); -we
|
|||
.analysis-page__header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 16px;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.analysis-page__header > div:first-child {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.analysis-split {
|
||||
display: flex;
|
||||
|
|
@ -544,14 +579,6 @@ a.analysis-split__nav-item {
|
|||
}
|
||||
}
|
||||
|
||||
/* 6-item nav - smaller labels */
|
||||
.nav-item span { font-size: 11px; }
|
||||
|
||||
/* 7-item nav scrollable */
|
||||
.bottom-nav { overflow-x: auto; }
|
||||
.nav-item span { font-size: 11px; }
|
||||
.nav-item { min-width: 60px; }
|
||||
|
||||
/* Header with profile avatar */
|
||||
.app-header { display:flex; align-items:center; justify-content:space-between; }
|
||||
.app-header a { display:flex; }
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import {
|
|||
LayoutDashboard,
|
||||
PlusSquare,
|
||||
TrendingUp,
|
||||
Target,
|
||||
BarChart2,
|
||||
Settings,
|
||||
Shield
|
||||
|
|
@ -18,6 +19,7 @@ function baseItems() {
|
|||
{ to: '/', label: 'Übersicht', end: true },
|
||||
{ to: '/capture', label: 'Erfassen' },
|
||||
{ to: '/history', label: 'Verlauf' },
|
||||
{ to: '/goals', label: 'Ziele', shortLabel: 'Ziele', end: true },
|
||||
{ to: '/analysis', label: 'Analyse' },
|
||||
{ to: '/settings', label: 'Einstellungen', shortLabel: 'Einst.' }
|
||||
]
|
||||
|
|
@ -29,6 +31,7 @@ export function getMainNavItems(isAdmin) {
|
|||
LayoutDashboard,
|
||||
PlusSquare,
|
||||
TrendingUp,
|
||||
Target,
|
||||
BarChart2,
|
||||
Settings
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React, { useState, useEffect, useMemo } from 'react'
|
||||
import { Brain, Trash2, ChevronDown, ChevronUp, Target } from 'lucide-react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { Brain, Trash2, ChevronDown, ChevronUp } from 'lucide-react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { api } from '../utils/api'
|
||||
import { useAuth } from '../context/AuthContext'
|
||||
import Markdown from '../utils/Markdown'
|
||||
|
|
@ -330,7 +330,6 @@ function InsightCard({ ins, onDelete, defaultOpen=false, prompts=[] }) {
|
|||
|
||||
export default function Analysis() {
|
||||
const { canUseAI } = useAuth()
|
||||
const navigate = useNavigate()
|
||||
const [prompts, setPrompts] = useState([])
|
||||
const [allInsights, setAllInsights] = useState([])
|
||||
const [loading, setLoading] = useState(null)
|
||||
|
|
@ -474,15 +473,14 @@ export default function Analysis() {
|
|||
return (
|
||||
<div className="analysis-page">
|
||||
<div className="analysis-page__header">
|
||||
<h1 className="page-title" style={{ margin: 0 }}>KI-Analyse</h1>
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-secondary"
|
||||
onClick={() => navigate('/goals')}
|
||||
style={{ fontSize: 13, padding: '6px 12px' }}
|
||||
>
|
||||
<Target size={14} /> Ziele
|
||||
</button>
|
||||
<div>
|
||||
<h1 className="page-title" style={{ margin: 0 }}>KI-Analyse</h1>
|
||||
<p style={{ fontSize: 12, color: 'var(--text3)', margin: '8px 0 0', lineHeight: 1.5, maxWidth: 520 }}>
|
||||
Ziele und Fokusbereiche steuern den Kontext der Auswertungen –{' '}
|
||||
<Link to="/goals" style={{ color: 'var(--accent)', fontWeight: 600 }}>unter „Ziele“ konfigurieren</Link>
|
||||
{' '}(auch über die untere Navigation).
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="tabs">
|
||||
|
|
|
|||
|
|
@ -256,6 +256,7 @@ export default function Dashboard() {
|
|||
const { activeProfile } = useProfile()
|
||||
|
||||
const [adminDeniedHint, setAdminDeniedHint] = useState(false)
|
||||
const [goalsCount, setGoalsCount] = useState(null)
|
||||
|
||||
const [stats, setStats] = useState(null)
|
||||
const [weights, setWeights] = useState([])
|
||||
|
|
@ -310,6 +311,13 @@ export default function Dashboard() {
|
|||
return () => window.clearTimeout(clear)
|
||||
}, [location.state, nav])
|
||||
|
||||
useEffect(() => {
|
||||
if (!activeProfile?.id) return
|
||||
api.listGoals()
|
||||
.then((list) => setGoalsCount(Array.isArray(list) ? list.length : 0))
|
||||
.catch(() => setGoalsCount(null))
|
||||
}, [activeProfile?.id])
|
||||
|
||||
if (loading) return <div className="empty-state"><div className="spinner"/></div>
|
||||
|
||||
const latestCal = calipers[0]
|
||||
|
|
@ -588,18 +596,26 @@ export default function Dashboard() {
|
|||
|
||||
<DashboardSection
|
||||
title="Ziele & Fokus"
|
||||
description="Trainingsmodus, Schwerpunkte und konkrete Ziele für die KI."
|
||||
description="Strategische Ziele und Schwerpunkte – eigener Menüpunkt „Ziele“, Kontext für KI und Dashboard."
|
||||
headerRight={
|
||||
<button type="button" className="btn btn-secondary" style={{ fontSize: 12, padding: '6px 12px' }}
|
||||
onClick={(e)=>{ e.stopPropagation(); nav('/goals') }}>
|
||||
Verwalten →
|
||||
Ziele bearbeiten →
|
||||
</button>
|
||||
}
|
||||
>
|
||||
<DashboardTile>
|
||||
<div className="card section-gap" style={{ cursor: 'pointer' }} onClick={()=>nav('/goals')}>
|
||||
<div style={{fontSize:12,color:'var(--text2)',padding:'8px 0'}}>
|
||||
Definiere deine Trainingsmodus und konkrete Ziele für bessere KI-Analysen
|
||||
{goalsCount != null && (
|
||||
<div style={{ fontSize: 13, fontWeight: 600, color: 'var(--text1)', marginBottom: 8 }}>
|
||||
{goalsCount === 0
|
||||
? 'Noch keine Ziele angelegt.'
|
||||
: `${goalsCount} ${goalsCount === 1 ? 'Ziel' : 'Ziele'} im System.`}
|
||||
</div>
|
||||
)}
|
||||
<div style={{ fontSize: 12, color: 'var(--text2)', padding: goalsCount != null ? '0 0 8px' : '8px 0' }}>
|
||||
Hier pflegst du Focus Areas, Meilensteine und Fortschritt – unabhängig von der KI-Analyse-Seite.
|
||||
Tippen zum Öffnen oder unten in der Navigation <strong>Ziele</strong> wählen.
|
||||
</div>
|
||||
</div>
|
||||
</DashboardTile>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useState, useEffect } from 'react'
|
||||
import { Save, Download, Upload, Check, LogOut, Key, BarChart3 } from 'lucide-react'
|
||||
import { Save, Download, Upload, Check, LogOut, Key, BarChart3, Target } from 'lucide-react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { useProfile } from '../context/ProfileContext'
|
||||
import { useAuth } from '../context/AuthContext'
|
||||
|
|
@ -428,6 +428,19 @@ export default function SettingsPage() {
|
|||
</button>
|
||||
</div>
|
||||
|
||||
<div className="card section-gap">
|
||||
<div className="card-title" style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
|
||||
<Target size={15} color="var(--accent)" /> Strategische Ziele
|
||||
</div>
|
||||
<p style={{ fontSize: 13, color: 'var(--text2)', marginBottom: 12, lineHeight: 1.6 }}>
|
||||
Konkrete Ziele, Focus Areas und Fortschritt – eigener Bereich{' '}
|
||||
<strong>Ziele</strong> in der Navigation (nicht in der KI-Analyse).
|
||||
</p>
|
||||
<Link to="/goals" className="btn btn-secondary btn-full" style={{ textAlign: 'center', textDecoration: 'none', boxSizing: 'border-box' }}>
|
||||
Zu den Zielen
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* Auth actions */}
|
||||
<div className="card section-gap">
|
||||
<div className="card-title">🔐 Konto</div>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user