Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions frontend/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -318,9 +318,8 @@ <h1>🌾 <span>SFDAP</span></h1>
<a class="nav-item" href="#users" data-action="navigate" data-arg="users" data-role="admin" style="display:none;">
<span class="icon" aria-hidden="true">👥</span> Kullanıcılar
</a>
<a class="nav-item" href="#auth" data-action="navigate" data-arg="auth">
<span class="icon" aria-hidden="true">👤</span> Hesabım
</a>
<!-- "Hesabım" sidebar'dan kaldırıldı: sağ üstteki kullanıcı çipine
tıklayınca zaten Hesabım (#auth) açılıyor (tüm roller için). -->
<!-- API Rehberi sidebar'dan çıkarıldı, header'a `</>` ikonu olarak taşındı.
Çiftçi-dostu UI için: çiftçi sekmeleri ile geliştirici aracını ayır. -->
</nav>
Expand Down Expand Up @@ -360,7 +359,7 @@ <h2 id="pageTitle">Dashboard</h2>
</div>
<!-- Kullanıcı rozeti — login sonrası refreshAuthState() doldurur.
REBUILD Faz 2 / Adım 7: rol-aware badge. Tıklayınca Hesabım. -->
<a class="user-badge" id="userBadge" href="#auth" style="display:none;"
<a class="user-badge" id="userBadge" href="#auth" data-action="navigate" data-arg="auth" style="display:none;"
aria-label="Hesap özeti — tıkla Hesabım sayfasına git"
title="Hesabım">
<span class="user-badge-role" id="userBadgeRole" data-role="farmer">çiftçi</span>
Expand All @@ -369,6 +368,7 @@ <h2 id="pageTitle">Dashboard</h2>
aria-label="Sahip olunan çiftlik sayısı" title="Çiftlikler">🚜&nbsp;0</span>
</a>
<a class="dev-link" href="/docs" target="_blank" rel="noopener"
data-role="admin,developer" style="display:none;"
aria-label="API Rehberi (Geliştiriciler için)"
title="API Rehberi · Geliştiriciler için (Swagger /docs)">&lt;/&gt;</a>
<button class="theme-toggle js-theme-toggle" id="themeToggle" aria-label="Tema değiştir" title="Tema değiştir">
Expand Down
22 changes: 22 additions & 0 deletions frontend/src/lib/charts.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,28 @@ export const chartTick = () => (_isLight() ? '#314257' : '#aeb9c9'); // ekse
export const chartLegend = () => (_isLight() ? '#1e293b' : '#dbe2ec'); // legend / başlık
export const chartGrid = () => (_isLight() ? 'rgba(20,80,140,.14)' : 'rgba(148,163,184,.16)'); // ızgara

// Tema değişince TÜM kayıtlı grafiklerin canvas-içi renklerini YERİNDE günceller
// (re-render/re-fetch/flash YOK). Accent tick'ler (amber sıcaklık / mavi nem
// data eksenleri) korunur. Toggle anında çağrılır → yazılar yeni temada görünür.
const _ACCENT = new Set(['#f59e0b', '#3b82f6']);
export function rethemeCharts() {
Object.values(charts).forEach(ch => {
if (!ch || !ch.options) return;
const lg = ch.options.plugins?.legend?.labels;
if (lg) lg.color = chartLegend();
const ttl = ch.options.plugins?.title;
if (ttl && ttl.color) ttl.color = chartLegend();
Object.values(ch.options.scales || {}).forEach(sc => {
if (!sc) return;
if (sc.ticks && !_ACCENT.has(sc.ticks.color)) sc.ticks.color = chartTick();
if (sc.grid && sc.grid.display !== false) sc.grid.color = chartGrid();
if (sc.pointLabels) sc.pointLabels.color = chartLegend();
if (sc.title && sc.title.color) sc.title.color = chartTick();
});
ch.update('none');
});
}

export function renderMoistureChart(data) {
const sorted = [...data].reverse();
const labels = sorted.map(d => new Date(d.recorded_at).toLocaleDateString('tr'));
Expand Down
9 changes: 6 additions & 3 deletions frontend/src/lib/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,19 @@ export function navigate(page, handlers, startHeroTipRotation) {
n.removeAttribute('aria-current');
});
document.getElementById(`page-${page}`).classList.add('active');
const navItem = document.querySelector(`[href="#${page}"]`);
// Hash'i mevcut sayfaya senkronla (history spam'siz) → refresh aynı sayfada kalır.
if (window.history?.replaceState) history.replaceState(null, '', `#${page}`);
const navItem = document.querySelector(`.nav-item[href="#${page}"]`);
if (navItem) {
navItem.classList.add('active');
navItem.setAttribute('aria-current', 'page');
}
document.getElementById('pageTitle').textContent = pageTitles[page][0];
document.getElementById('pageSubtitle').textContent = pageTitles[page][1];
// Focus the <main> programmatically for a11y
// Sayfa her zaman TEPEDEN açılsın + a11y odağı (odak kaydırmasın → preventScroll).
window.scrollTo(0, 0);
const main = document.getElementById('main-content');
if (main) main.focus({ preventScroll: false });
if (main) main.focus({ preventScroll: true });

// Load page data
const handler = handlers[page];
Expand Down
6 changes: 4 additions & 2 deletions frontend/src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { showToast, updateStatus, updateClock } from "./lib/utils.js";
import { pageTitles, toggleSidebar, initHashRouter, navigate as _navigateCore } from "./lib/router.js";
import { getCurrentUser, setCurrentUser, setApiOnline } from "./lib/session.js";
import { setNavigate } from "./lib/nav.js";
import { rethemeCharts } from "./lib/charts.js";

// ─── Sayfa modülleri ─────────────────────────────────────────
import {
Expand Down Expand Up @@ -233,8 +234,9 @@ function initTheme() {
const next = current === 'light' ? 'dark' : 'light';
applyTheme(next);
localStorage.setItem(STORAGE_KEY, next);
// Sayfa yeniden yüklenmiyor — toast bildirimi çıkmasın diye.
// Chart.js renkleri mevcut sayfada eski temada kalır; sayfa değişince güncellenir.
// Chart.js canvas'ı CSS değişkenlerini almaz → tema değişince renkleri
// YERİNDE güncelle ki yazılar yeni temada görünür kalsın (refresh gerekmesin).
rethemeCharts();
}));

function applyTheme(theme) {
Expand Down
Loading