Improve tab scrolling with arrows

This commit is contained in:
2025-12-22 19:50:55 +01:00
parent 69c0fd7506
commit 1f52680721
18 changed files with 378 additions and 37 deletions

View File

@@ -1,6 +1,7 @@
import { useEffect, useState } from 'react';
import { useTranslation } from '../contexts/LanguageContext';
import { useSidebar } from '../contexts/SidebarContext';
import TabsScroller from '../components/TabsScroller';
import { apiKeysAPI } from '../api/client';
import type { ApiKeyItem } from '../api/client';
import '../styles/APIKeys.css';
@@ -89,14 +90,14 @@ export default function APIKeys() {
return (
<main className="main-content api-keys-root">
<div className="page-tabs-container">
<div className="page-tabs-slider">
<TabsScroller className="page-tabs-slider">
<button className="mobile-menu-btn" onClick={toggleMobileMenu} aria-label={t.theme.toggleMenu}>
<span className="material-symbols-outlined">menu</span>
</button>
<div className="page-title-section">
<span className="page-title-text">{t.apiKeysPage.title}</span>
</div>
</div>
</TabsScroller>
</div>
<div className="page-content">
@@ -185,4 +186,3 @@ export default function APIKeys() {
</main>
);
}

View File

@@ -2,6 +2,7 @@ import { useState } from 'react';
import { useAuth } from '../contexts/AuthContext';
import { useTranslation } from '../contexts/LanguageContext';
import { useSidebar } from '../contexts/SidebarContext';
import TabsScroller from '../components/TabsScroller';
import GeneralTab from '../components/admin/GeneralTab';
import UsersTab from '../components/admin/UsersTab';
import { SwipeTabs } from '../components/SwipeTabs';
@@ -24,7 +25,7 @@ export default function AdminPanel({ initialTab = 'general' }: { initialTab?: Ta
return (
<main className="main-content admin-panel-root">
<div className="page-tabs-container">
<div className="page-tabs-slider">
<TabsScroller className="page-tabs-slider">
<button className="mobile-menu-btn" onClick={toggleMobileMenu} aria-label={t.theme.toggleMenu}>
<span className="material-symbols-outlined">menu</span>
</button>
@@ -46,7 +47,7 @@ export default function AdminPanel({ initialTab = 'general' }: { initialTab?: Ta
<span className="material-symbols-outlined">group</span>
<span>{t.admin.usersTab}</span>
</button>
</div>
</TabsScroller>
</div>
<SwipeTabs

View File

@@ -1,5 +1,6 @@
import { useTranslation } from '../contexts/LanguageContext';
import { useSidebar } from '../contexts/SidebarContext';
import TabsScroller from '../components/TabsScroller';
export default function Dashboard() {
const { t } = useTranslation();
@@ -8,14 +9,14 @@ export default function Dashboard() {
return (
<main className="main-content">
<div className="page-tabs-container">
<div className="page-tabs-slider">
<TabsScroller className="page-tabs-slider">
<button className="mobile-menu-btn" onClick={toggleMobileMenu} aria-label={t.theme.toggleMenu}>
<span className="material-symbols-outlined">menu</span>
</button>
<div className="page-title-section">
<span className="page-title-text">{t.dashboard.title}</span>
</div>
</div>
</TabsScroller>
</div>
<div className="page-content">

View File

@@ -1,5 +1,6 @@
import { useTranslation } from '../contexts/LanguageContext';
import { useSidebar } from '../contexts/SidebarContext';
import TabsScroller from '../components/TabsScroller';
import '../styles/AdminPanel.css';
export default function Feature1() {
@@ -9,14 +10,14 @@ export default function Feature1() {
return (
<main className="main-content">
<div className="page-tabs-container">
<div className="page-tabs-slider">
<TabsScroller className="page-tabs-slider">
<button className="mobile-menu-btn" onClick={toggleMobileMenu} aria-label={t.theme.toggleMenu}>
<span className="material-symbols-outlined">menu</span>
</button>
<div className="page-title-section">
<span className="page-title-text">{t.feature1.title}</span>
</div>
</div>
</TabsScroller>
</div>
<div className="page-content">

View File

@@ -1,5 +1,6 @@
import { useTranslation } from '../contexts/LanguageContext';
import { useSidebar } from '../contexts/SidebarContext';
import TabsScroller from '../components/TabsScroller';
import '../styles/AdminPanel.css';
export default function Feature2() {
@@ -9,14 +10,14 @@ export default function Feature2() {
return (
<main className="main-content">
<div className="page-tabs-container">
<div className="page-tabs-slider">
<TabsScroller className="page-tabs-slider">
<button className="mobile-menu-btn" onClick={toggleMobileMenu} aria-label={t.theme.toggleMenu}>
<span className="material-symbols-outlined">menu</span>
</button>
<div className="page-title-section">
<span className="page-title-text">{t.features.feature2}</span>
</div>
</div>
</TabsScroller>
</div>
<div className="page-content">
@@ -32,4 +33,3 @@ export default function Feature2() {
</main>
);
}

View File

@@ -1,5 +1,6 @@
import { useTranslation } from '../contexts/LanguageContext';
import { useSidebar } from '../contexts/SidebarContext';
import TabsScroller from '../components/TabsScroller';
import '../styles/AdminPanel.css';
export default function Feature3() {
@@ -9,14 +10,14 @@ export default function Feature3() {
return (
<main className="main-content">
<div className="page-tabs-container">
<div className="page-tabs-slider">
<TabsScroller className="page-tabs-slider">
<button className="mobile-menu-btn" onClick={toggleMobileMenu} aria-label={t.theme.toggleMenu}>
<span className="material-symbols-outlined">menu</span>
</button>
<div className="page-title-section">
<span className="page-title-text">{t.features.feature3}</span>
</div>
</div>
</TabsScroller>
</div>
<div className="page-content">
@@ -32,4 +33,3 @@ export default function Feature3() {
</main>
);
}

View File

@@ -1,6 +1,7 @@
import { useEffect, useState } from 'react';
import { useTranslation } from '../contexts/LanguageContext';
import { useSidebar } from '../contexts/SidebarContext';
import TabsScroller from '../components/TabsScroller';
import { useNotifications } from '../contexts/NotificationsContext';
import { notificationsAPI } from '../api/client';
import type { NotificationItem } from '../api/client';
@@ -95,14 +96,14 @@ export default function Notifications() {
return (
<main className="main-content notifications-root">
<div className="page-tabs-container">
<div className="page-tabs-slider">
<TabsScroller className="page-tabs-slider">
<button className="mobile-menu-btn" onClick={toggleMobileMenu} aria-label={t.theme.toggleMenu}>
<span className="material-symbols-outlined">menu</span>
</button>
<div className="page-title-section">
<span className="page-title-text">{t.notificationsPage.title}</span>
</div>
</div>
</TabsScroller>
</div>
<div className="page-content page-content--narrow">

View File

@@ -1,6 +1,7 @@
import { useEffect, useMemo, useRef, useState } from 'react';
import { useTranslation } from '../contexts/LanguageContext';
import { useSidebar } from '../contexts/SidebarContext';
import TabsScroller from '../components/TabsScroller';
import '../styles/Search.css';
type SearchResult = {
@@ -77,14 +78,14 @@ export default function Search() {
return (
<main className="main-content search-root">
<div className="page-tabs-container">
<div className="page-tabs-slider">
<TabsScroller className="page-tabs-slider">
<button className="mobile-menu-btn" onClick={toggleMobileMenu} aria-label={t.theme.toggleMenu}>
<span className="material-symbols-outlined">menu</span>
</button>
<div className="page-title-section">
<span className="page-title-text">{t.searchPage.title}</span>
</div>
</div>
</TabsScroller>
</div>
<div className="page-content">

View File

@@ -1,6 +1,7 @@
import { useEffect, useState } from 'react';
import { useTranslation } from '../contexts/LanguageContext';
import { useSidebar } from '../contexts/SidebarContext';
import TabsScroller from '../components/TabsScroller';
import { sessionsAPI, twoFactorAPI } from '../api/client';
import type { UserSession } from '../api/client';
import '../styles/SettingsPage.css';
@@ -152,14 +153,14 @@ export default function Settings() {
return (
<main className="main-content settings-page-root">
<div className="page-tabs-container">
<div className="page-tabs-slider">
<TabsScroller className="page-tabs-slider">
<button className="mobile-menu-btn" onClick={toggleMobileMenu} aria-label={t.theme.toggleMenu}>
<span className="material-symbols-outlined">menu</span>
</button>
<div className="page-title-section">
<span className="page-title-text">{t.settings.title}</span>
</div>
</div>
</TabsScroller>
</div>
<div className="page-content page-content--narrow settings-tab-content">

View File

@@ -1,6 +1,7 @@
import { useEffect, useMemo, useState } from 'react';
import type { FormEvent } from 'react';
import Sidebar from '../components/Sidebar';
import TabsScroller from '../components/TabsScroller';
import { useAuth } from '../contexts/AuthContext';
import { useTranslation } from '../contexts/LanguageContext';
import { useSidebar } from '../contexts/SidebarContext';
@@ -181,7 +182,7 @@ export default function Users() {
<Sidebar />
<main className="main-content users-root">
<div className="page-tabs-container">
<div className="page-tabs-slider">
<TabsScroller className="page-tabs-slider">
<button className="mobile-menu-btn" onClick={toggleMobileMenu} aria-label={t.theme.toggleMenu}>
<span className="material-symbols-outlined">menu</span>
</button>
@@ -192,7 +193,7 @@ export default function Users() {
<span className="material-symbols-outlined">add</span>
<span>{t.usersPage.addUser}</span>
</button>
</div>
</TabsScroller>
</div>
<div className="page-content users-page">

View File

@@ -1,6 +1,7 @@
import { useEffect, useMemo, useState } from 'react';
import { useTranslation } from '../../contexts/LanguageContext';
import { useSidebar } from '../../contexts/SidebarContext';
import TabsScroller from '../../components/TabsScroller';
import { analyticsAPI } from '../../api/client';
import type { AnalyticsOverview } from '../../api/client';
import '../../styles/AdminAnalytics.css';
@@ -46,14 +47,14 @@ export default function Analytics() {
return (
<main className="main-content admin-analytics-root">
<div className="page-tabs-container">
<div className="page-tabs-slider">
<TabsScroller className="page-tabs-slider">
<button className="mobile-menu-btn" onClick={toggleMobileMenu} aria-label={t.theme.toggleMenu}>
<span className="material-symbols-outlined">menu</span>
</button>
<div className="page-title-section">
<span className="page-title-text">{t.analyticsPage.title}</span>
</div>
</div>
</TabsScroller>
</div>
<div className="page-content">
@@ -151,4 +152,3 @@ export default function Analytics() {
</main>
);
}

View File

@@ -1,6 +1,7 @@
import { useEffect, useMemo, useState } from 'react';
import { useTranslation } from '../../contexts/LanguageContext';
import { useSidebar } from '../../contexts/SidebarContext';
import TabsScroller from '../../components/TabsScroller';
import { auditAPI } from '../../api/client';
import type { AuditLogItem } from '../../api/client';
import '../../styles/AdminAudit.css';
@@ -59,14 +60,14 @@ export default function AuditLogs() {
return (
<main className="main-content admin-audit-root">
<div className="page-tabs-container">
<div className="page-tabs-slider">
<TabsScroller className="page-tabs-slider">
<button className="mobile-menu-btn" onClick={toggleMobileMenu} aria-label={t.theme.toggleMenu}>
<span className="material-symbols-outlined">menu</span>
</button>
<div className="page-title-section">
<span className="page-title-text">{t.auditPage.title}</span>
</div>
</div>
</TabsScroller>
</div>
<div className="page-content">
@@ -163,4 +164,3 @@ export default function AuditLogs() {
</main>
);
}

View File

@@ -6,6 +6,7 @@ import { useModules, TOGGLEABLE_MODULES } from '../../contexts/ModulesContext';
import type { ModuleId } from '../../contexts/ModulesContext';
import Feature1Tab from '../../components/admin/Feature1Tab';
import { SwipeTabs } from '../../components/SwipeTabs';
import TabsScroller from '../../components/TabsScroller';
import '../../styles/AdminPanel.css';
type TabId = 'config' | 'dashboard' | 'feature1' | 'feature2' | 'feature3' | 'search' | 'notifications';
@@ -743,7 +744,7 @@ export default function Features() {
return (
<main className="main-content admin-panel-root">
<div className="page-tabs-container">
<div className="page-tabs-slider" ref={tabsContainerRef}>
<TabsScroller className="page-tabs-slider" ref={tabsContainerRef}>
<button className="mobile-menu-btn" onClick={toggleMobileMenu} aria-label={t.theme.toggleMenu}>
<span className="material-symbols-outlined">menu</span>
</button>
@@ -774,7 +775,7 @@ export default function Features() {
</button>
);
})}
</div>
</TabsScroller>
</div>
<SwipeTabs

View File

@@ -2,6 +2,7 @@ import { useState, useEffect } from 'react';
import { useTranslation } from '../../contexts/LanguageContext';
import { useSidebar } from '../../contexts/SidebarContext';
import Sidebar from '../../components/Sidebar';
import TabsScroller from '../../components/TabsScroller';
import { settingsAPI } from '../../api/client';
import '../../styles/Settings.css';
@@ -60,14 +61,14 @@ export default function Settings() {
<Sidebar />
<main className="main-content settings-root">
<div className="page-tabs-container">
<div className="page-tabs-slider">
<TabsScroller className="page-tabs-slider">
<button className="mobile-menu-btn" onClick={toggleMobileMenu} aria-label={t.theme.toggleMenu}>
<span className="material-symbols-outlined">menu</span>
</button>
<div className="page-title-section">
<span className="page-title-text">{t.settings.title}</span>
</div>
</div>
</TabsScroller>
</div>
<div className="page-content page-content--narrow">

View File

@@ -1,6 +1,7 @@
import { useAuth } from '../../contexts/AuthContext';
import { useTranslation } from '../../contexts/LanguageContext';
import { useSidebar } from '../../contexts/SidebarContext';
import TabsScroller from '../../components/TabsScroller';
import '../../styles/AdminPanel.css';
export default function Sources() {
@@ -15,14 +16,14 @@ export default function Sources() {
return (
<main className="main-content admin-panel-root">
<div className="admin-tabs-container">
<div className="admin-tabs-slider">
<TabsScroller className="admin-tabs-slider">
<button className="mobile-menu-btn" onClick={toggleMobileMenu} aria-label={t.theme.toggleMenu}>
<span className="material-symbols-outlined">menu</span>
</button>
<div className="admin-title-section">
<span className="admin-title-text">{t.sourcesPage.title}</span>
</div>
</div>
</TabsScroller>
</div>
<div className="admin-tab-content">

View File

@@ -7,6 +7,7 @@ import { useSidebar } from '../../contexts/SidebarContext';
import type { SidebarMode } from '../../contexts/SidebarContext';
import { ChromePicker, HuePicker } from 'react-color';
import { SwipeTabs } from '../../components/SwipeTabs';
import TabsScroller from '../../components/TabsScroller';
import '../../styles/ThemeSettings.css';
type ThemeTab = 'colors' | 'appearance' | 'preview' | 'advanced';
@@ -660,7 +661,7 @@ export default function ThemeSettings() {
)}
{/* Modern Tab Navigation */}
<div className="page-tabs-container">
<div className="page-tabs-slider">
<TabsScroller className="page-tabs-slider">
<button className="mobile-menu-btn" onClick={toggleMobileMenu} aria-label={t.theme.toggleMenu}>
<span className="material-symbols-outlined">menu</span>
</button>
@@ -706,7 +707,7 @@ export default function ThemeSettings() {
<span>{t.theme.advancedTab}</span>
</button>
)}
</div>
</TabsScroller>
</div>
<SwipeTabs