Merge pull request #17 from GoncaloRodri/feature/fixes-mobile-nav
fix: portfolio values, Yahoo UA header, mobile hamburger nav
This commit is contained in:
commit
1b9284801c
@ -413,17 +413,67 @@
|
|||||||
.animate-on-scroll:nth-child(4) { transition-delay: 0.21s; }
|
.animate-on-scroll:nth-child(4) { transition-delay: 0.21s; }
|
||||||
.animate-on-scroll:nth-child(5) { transition-delay: 0.28s; }
|
.animate-on-scroll:nth-child(5) { transition-delay: 0.28s; }
|
||||||
|
|
||||||
|
/* ── Hamburger / mobile drawer ────────────────────────────────────── */
|
||||||
|
.nav-hamburger {
|
||||||
|
display: none;
|
||||||
|
width: 36px; height: 36px;
|
||||||
|
border: none; background: none; cursor: pointer;
|
||||||
|
color: var(--text2);
|
||||||
|
flex-direction: column; justify-content: center; align-items: center; gap: 5px;
|
||||||
|
border-radius: var(--radius-sm);
|
||||||
|
transition: background 0.18s;
|
||||||
|
}
|
||||||
|
.nav-hamburger:hover { background: var(--surface2); }
|
||||||
|
.nav-hamburger span {
|
||||||
|
display: block; width: 20px; height: 2px;
|
||||||
|
background: currentColor; border-radius: 2px;
|
||||||
|
transition: transform 0.25s ease, opacity 0.25s ease;
|
||||||
|
}
|
||||||
|
.nav-hamburger.open span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
|
||||||
|
.nav-hamburger.open span:nth-child(2) { opacity: 0; }
|
||||||
|
.nav-hamburger.open span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
|
||||||
|
|
||||||
|
.nav-drawer {
|
||||||
|
display: none;
|
||||||
|
position: fixed; inset: var(--nav-h) 0 0 0;
|
||||||
|
background: var(--bg);
|
||||||
|
z-index: 199;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 12px 16px 32px;
|
||||||
|
flex-direction: column; gap: 4px;
|
||||||
|
animation: slideIn 0.2s ease-out both;
|
||||||
|
}
|
||||||
|
.nav-drawer.open { display: flex; }
|
||||||
|
.nav-drawer a, .nav-drawer-section-label {
|
||||||
|
display: block;
|
||||||
|
padding: 11px 14px;
|
||||||
|
border-radius: var(--radius-sm);
|
||||||
|
font-size: 15px; font-weight: 500;
|
||||||
|
color: var(--text2); text-decoration: none;
|
||||||
|
transition: all 0.15s;
|
||||||
|
}
|
||||||
|
.nav-drawer a:hover { color: var(--text); background: var(--surface2); }
|
||||||
|
.nav-drawer a.active { color: var(--accent2); background: var(--accent-glow); }
|
||||||
|
.nav-drawer-section-label {
|
||||||
|
font-size: 11px; font-weight: 600; letter-spacing: 0.08em;
|
||||||
|
text-transform: uppercase; color: var(--text3);
|
||||||
|
padding-top: 16px; padding-bottom: 4px;
|
||||||
|
}
|
||||||
|
.nav-drawer hr { border: none; border-top: 1px solid var(--border); margin: 8px 0; }
|
||||||
|
|
||||||
/* ── Responsive ──────────────────────────────────────────────────── */
|
/* ── Responsive ──────────────────────────────────────────────────── */
|
||||||
@media (max-width: 900px) {
|
@media (max-width: 900px) {
|
||||||
.grid-2 { grid-template-columns: 1fr; }
|
.grid-2 { grid-template-columns: 1fr; }
|
||||||
}
|
}
|
||||||
@media (max-width: 600px) {
|
@media (max-width: 720px) {
|
||||||
.nav { padding: 0 12px; gap: 2px; overflow-x: auto; }
|
.nav-hamburger { display: flex; }
|
||||||
.nav a:not(.nav-brand) { padding: 6px 7px; font-size: 12px; }
|
.nav > a:not(.nav-brand),
|
||||||
|
.nav > .nav-group,
|
||||||
|
.nav > .nav-spacer,
|
||||||
|
.nav-email { display: none; }
|
||||||
.container { padding: 16px 12px 32px; }
|
.container { padding: 16px 12px 32px; }
|
||||||
.grid { grid-template-columns: 1fr 1fr; }
|
.grid { grid-template-columns: 1fr 1fr; }
|
||||||
.card { padding: 16px; }
|
.card { padding: 16px; }
|
||||||
.nav-email { display: none; }
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
@ -469,8 +519,32 @@
|
|||||||
<div class="nav-spacer"></div>
|
<div class="nav-spacer"></div>
|
||||||
<span class="nav-email">{{.Email}}</span>
|
<span class="nav-email">{{.Email}}</span>
|
||||||
<button class="theme-btn" id="theme-toggle" title="Toggle dark/light mode">🌙</button>
|
<button class="theme-btn" id="theme-toggle" title="Toggle dark/light mode">🌙</button>
|
||||||
|
<button class="nav-hamburger" id="nav-hamburger" aria-label="Menu">
|
||||||
|
<span></span><span></span><span></span>
|
||||||
|
</button>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
<!-- Mobile drawer -->
|
||||||
|
<div class="nav-drawer" id="nav-drawer">
|
||||||
|
<a href="/" class="{{if eq .Route "dashboard"}}active{{end}}">Dashboard</a>
|
||||||
|
<a href="/transactions" class="{{if eq .Route "transactions"}}active{{end}}">Transactions</a>
|
||||||
|
<a href="/portfolio" class="{{if eq .Route "portfolio"}}active{{end}}">Portfolio</a>
|
||||||
|
<a href="/goals" class="{{if eq .Route "goals"}}active{{end}}">Goals</a>
|
||||||
|
<a href="/people" class="{{if eq .Route "people"}}active{{end}}">People</a>
|
||||||
|
<hr>
|
||||||
|
<span class="nav-drawer-section-label">Analysis</span>
|
||||||
|
<a href="/reports" class="{{if eq .Route "reports"}}active{{end}}">Reports</a>
|
||||||
|
<a href="/projections" class="{{if eq .Route "projections"}}active{{end}}">Projections</a>
|
||||||
|
<a href="/tax" class="{{if eq .Route "tax"}}active{{end}}">Tax</a>
|
||||||
|
<a href="/networth" class="{{if eq .Route "networth"}}active{{end}}">Net Worth</a>
|
||||||
|
<a href="/simulator" class="{{if eq .Route "simulator"}}active{{end}}">What If</a>
|
||||||
|
<hr>
|
||||||
|
<span class="nav-drawer-section-label">Settings</span>
|
||||||
|
<a href="/settings?tab=accounts" class="{{if eq .Route "settings"}}active{{end}}">Accounts & Categories</a>
|
||||||
|
<a href="/import" class="{{if eq .Route "import"}}active{{end}}">Import CSV</a>
|
||||||
|
<a href="/auto-import" class="{{if eq .Route "auto-import"}}active{{end}}">Import Guide</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
{{block "content" .}}{{end}}
|
{{block "content" .}}{{end}}
|
||||||
</div>
|
</div>
|
||||||
@ -493,6 +567,22 @@
|
|||||||
btn.addEventListener('click', () =>
|
btn.addEventListener('click', () =>
|
||||||
applyTheme(html.getAttribute('data-theme') === 'dark' ? 'light' : 'dark'));
|
applyTheme(html.getAttribute('data-theme') === 'dark' ? 'light' : 'dark'));
|
||||||
|
|
||||||
|
/* ── Mobile hamburger ─────────────────────────────────────────── */
|
||||||
|
const hamburger = document.getElementById('nav-hamburger');
|
||||||
|
const drawer = document.getElementById('nav-drawer');
|
||||||
|
hamburger.addEventListener('click', () => {
|
||||||
|
const open = drawer.classList.toggle('open');
|
||||||
|
hamburger.classList.toggle('open', open);
|
||||||
|
document.body.style.overflow = open ? 'hidden' : '';
|
||||||
|
});
|
||||||
|
drawer.querySelectorAll('a').forEach(a =>
|
||||||
|
a.addEventListener('click', () => {
|
||||||
|
drawer.classList.remove('open');
|
||||||
|
hamburger.classList.remove('open');
|
||||||
|
document.body.style.overflow = '';
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
/* ── Animated counter ─────────────────────────────────────────── */
|
/* ── Animated counter ─────────────────────────────────────────── */
|
||||||
function animateCounter(el) {
|
function animateCounter(el) {
|
||||||
const target = parseFloat(el.getAttribute('data-target'));
|
const target = parseFloat(el.getAttribute('data-target'));
|
||||||
|
|||||||
6
apps/finance/services/api/main/testdata/traderepublic_securities.csv
vendored
Normal file
6
apps/finance/services/api/main/testdata/traderepublic_securities.csv
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
date,name,isin,type,quantity,price,total,currency
|
||||||
|
2024-01-10,iShares S&P 500 IT Sector,IE00B3WJKG14,buy,0.5,60.00,30.00,EUR
|
||||||
|
2024-01-15,Vanguard FTSE All-World,IE00B3RBWM25,buy,1.0,100.00,100.00,EUR
|
||||||
|
2024-01-20,iShares Core S&P 500,IE00B5BMR087,buy,2.0,50.00,100.00,EUR
|
||||||
|
2024-02-05,iShares S&P 500 IT Sector,IE00B3WJKG14,buy,1.0,62.00,62.00,EUR
|
||||||
|
2024-02-10,Vanguard FTSE All-World,IE00B3RBWM25,buy,0.5,105.00,52.50,EUR
|
||||||
|
Loading…
x
Reference in New Issue
Block a user