feat: Fix Overview always active, add Refresh button, add Logout in standalone
This commit is contained in:
@@ -259,11 +259,34 @@ function AddonRoute({ config }: { config: any }) {
|
|||||||
|
|
||||||
function Header({ onFullscreen, fullscreen, showToggle = true }: { onFullscreen: () => void; fullscreen: boolean; showToggle?: boolean }) {
|
function Header({ onFullscreen, fullscreen, showToggle = true }: { onFullscreen: () => void; fullscreen: boolean; showToggle?: boolean }) {
|
||||||
const siteTitle = (window as any).wnw?.siteTitle || 'WooNooW';
|
const siteTitle = (window as any).wnw?.siteTitle || 'WooNooW';
|
||||||
|
const isStandalone = window.WNW_CONFIG?.standaloneMode ?? false;
|
||||||
|
|
||||||
|
const handleLogout = async () => {
|
||||||
|
try {
|
||||||
|
await fetch(window.WNW_CONFIG.restUrl + '/auth/logout', {
|
||||||
|
method: 'POST',
|
||||||
|
credentials: 'include',
|
||||||
|
});
|
||||||
|
window.location.reload();
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Logout failed:', err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<header className={`h-16 border-b border-border flex items-center px-4 justify-between sticky ${fullscreen ? `top-0` : `top-[32px]`} z-40 bg-background md:bg-background/95 md:backdrop-blur md:supports-[backdrop-filter]:bg-background/60`}>
|
<header className={`h-16 border-b border-border flex items-center px-4 justify-between sticky ${fullscreen ? `top-0` : `top-[32px]`} z-40 bg-background md:bg-background/95 md:backdrop-blur md:supports-[backdrop-filter]:bg-background/60`}>
|
||||||
<div className="font-semibold">{siteTitle}</div>
|
<div className="font-semibold">{siteTitle}</div>
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<div className="text-sm opacity-70 hidden sm:block">{window.WNW_API?.isDev ? 'Dev Server' : 'Production'}</div>
|
<div className="text-sm opacity-70 hidden sm:block">{window.WNW_API?.isDev ? 'Dev Server' : 'Production'}</div>
|
||||||
|
{isStandalone && (
|
||||||
|
<button
|
||||||
|
onClick={handleLogout}
|
||||||
|
className="inline-flex items-center gap-2 border rounded-md px-3 py-2 text-sm hover:bg-accent hover:text-accent-foreground"
|
||||||
|
title="Logout"
|
||||||
|
>
|
||||||
|
<span>{__('Logout')}</span>
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
{showToggle && (
|
{showToggle && (
|
||||||
<button
|
<button
|
||||||
onClick={onFullscreen}
|
onClick={onFullscreen}
|
||||||
|
|||||||
@@ -1,16 +1,24 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Link, useLocation } from 'react-router-dom';
|
import { Link, useLocation } from 'react-router-dom';
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||||
import { DummyDataToggle } from '@/components/DummyDataToggle';
|
import { Button } from '@/components/ui/button';
|
||||||
import { useDashboardContext } from '@/contexts/DashboardContext';
|
import { RefreshCw } from 'lucide-react';
|
||||||
|
import { useDashboardPeriod } from '@/hooks/useDashboardPeriod';
|
||||||
|
import { DummyDataToggle } from '../DummyDataToggle';
|
||||||
import { __ } from '@/lib/i18n';
|
import { __ } from '@/lib/i18n';
|
||||||
|
import { useQueryClient } from '@tanstack/react-query';
|
||||||
import type { SubItem } from '@/nav/tree';
|
import type { SubItem } from '@/nav/tree';
|
||||||
|
|
||||||
type Props = { items?: SubItem[]; fullscreen?: boolean };
|
type Props = { items?: SubItem[]; fullscreen?: boolean };
|
||||||
|
|
||||||
export default function DashboardSubmenuBar({ items = [], fullscreen = false }: Props) {
|
export default function DashboardSubmenuBar({ items = [], fullscreen = false }: Props) {
|
||||||
const { period, setPeriod } = useDashboardContext();
|
const { period, useDummy } = useDashboardPeriod();
|
||||||
const { pathname } = useLocation();
|
const { pathname } = useLocation();
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
const handleRefresh = () => {
|
||||||
|
queryClient.invalidateQueries({ queryKey: ['analytics'] });
|
||||||
|
};
|
||||||
|
|
||||||
if (items.length === 0) return null;
|
if (items.length === 0) return null;
|
||||||
|
|
||||||
@@ -56,20 +64,21 @@ export default function DashboardSubmenuBar({ items = [], fullscreen = false }:
|
|||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Period Selector & Dummy Toggle */}
|
{/* Refresh & Dummy Toggle */}
|
||||||
<div className="flex items-center gap-2 flex-shrink-0">
|
<div className="flex items-center gap-2 flex-shrink-0">
|
||||||
|
{!useDummy && (
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
onClick={handleRefresh}
|
||||||
|
className="h-8"
|
||||||
|
title={__('Refresh data (cached for 5 minutes)')}
|
||||||
|
>
|
||||||
|
<RefreshCw className="w-4 h-4 mr-1" />
|
||||||
|
{__('Refresh')}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
<DummyDataToggle />
|
<DummyDataToggle />
|
||||||
<Select value={period} onValueChange={setPeriod}>
|
|
||||||
<SelectTrigger className="w-[140px] h-8">
|
|
||||||
<SelectValue />
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent>
|
|
||||||
<SelectItem value="7">{__('Last 7 days')}</SelectItem>
|
|
||||||
<SelectItem value="14">{__('Last 14 days')}</SelectItem>
|
|
||||||
<SelectItem value="30">{__('Last 30 days')}</SelectItem>
|
|
||||||
<SelectItem value="all">{__('All Time')}</SelectItem>
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ function getStaticFallbackTree(): MainNode[] {
|
|||||||
path: '/',
|
path: '/',
|
||||||
icon: 'layout-dashboard',
|
icon: 'layout-dashboard',
|
||||||
children: [
|
children: [
|
||||||
{ label: 'Overview', mode: 'spa', path: '/dashboard' },
|
{ label: 'Overview', mode: 'spa', path: '/dashboard', exact: true },
|
||||||
{ label: 'Revenue', mode: 'spa', path: '/dashboard/revenue' },
|
{ label: 'Revenue', mode: 'spa', path: '/dashboard/revenue' },
|
||||||
{ label: 'Orders', mode: 'spa', path: '/dashboard/orders' },
|
{ label: 'Orders', mode: 'spa', path: '/dashboard/orders' },
|
||||||
{ label: 'Products', mode: 'spa', path: '/dashboard/products' },
|
{ label: 'Products', mode: 'spa', path: '/dashboard/products' },
|
||||||
|
|||||||
Reference in New Issue
Block a user