stock request
This commit is contained in:
161
src/App.tsx
161
src/App.tsx
@@ -4,6 +4,7 @@
|
||||
*/
|
||||
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Routes, Route, Navigate, useLocation, useNavigate } from 'react-router-dom';
|
||||
import {
|
||||
Network,
|
||||
Truck,
|
||||
@@ -29,7 +30,8 @@ import {
|
||||
Layers,
|
||||
Store,
|
||||
Settings,
|
||||
LayoutDashboard
|
||||
LayoutDashboard,
|
||||
Users
|
||||
} from 'lucide-react';
|
||||
|
||||
import { MainSection } from './types';
|
||||
@@ -37,9 +39,10 @@ import {
|
||||
useFiestaTenantLocations,
|
||||
useFiestaLocationSummary,
|
||||
useFiestaUpdateLocation,
|
||||
useFiestaCreateLocation,
|
||||
useFiestaOrderSummary,
|
||||
} from './services/fiestaQueries';
|
||||
import { FIESTA_TENANT_ID, str as fstr } from './services/fiestaApi';
|
||||
import { FIESTA_TENANT_ID, str as fstr, num as fnum } from './services/fiestaApi';
|
||||
import Sidebar from './components/Sidebar';
|
||||
import Header from './components/Header';
|
||||
import DashboardView from './components/DashboardView';
|
||||
@@ -97,13 +100,14 @@ export default function App() {
|
||||
};
|
||||
|
||||
// Navigation indicators states
|
||||
const [currentSection, setCurrentSection] = useState<MainSection>('dashboard');
|
||||
const [selectedStore, setSelectedStore] = useState<{ locationid?: number; name: string; zone: string; deliveries: number; sales: string; orders?: number; staff: string; color: string; status: string } | null>(null);
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const handleSetSection = (sec: MainSection) => {
|
||||
setCurrentSection(sec);
|
||||
setSelectedStore(null);
|
||||
};
|
||||
// Derive current section from URL path, default to 'dashboard'
|
||||
const pathParts = location.pathname.split('/');
|
||||
const currentSection = (pathParts.includes('admin') ? pathParts[pathParts.length - 1] : 'dashboard') as MainSection;
|
||||
|
||||
const [selectedStore, setSelectedStore] = useState<{ locationid?: number; name: string; zone: string; deliveries: number; sales: string; orders?: number; staff: string; color: string; status: string } | null>(null);
|
||||
|
||||
const [isCoimbatoreView, setIsCoimbatoreView] = useState(false);
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
@@ -474,31 +478,7 @@ export default function App() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Live Sparkline Trend Histogram */}
|
||||
<div className="mt-4 pt-3.5 border-t border-zinc-100">
|
||||
<div className="flex justify-between items-center text-[8px] text-zinc-400 font-bold uppercase tracking-widest mb-1.5">
|
||||
<span>Speed Index (Live Feed)</span>
|
||||
<span className="text-[#662582] flex items-center gap-0.5 text-[8px] font-bold">
|
||||
<Activity className="w-2.5 h-2.5 animate-pulse" /> Live
|
||||
</span>
|
||||
</div>
|
||||
<div className="h-6 flex items-end gap-1">
|
||||
{[30, 48, 25, 62, 54, 75, 42, 80, Math.min(95, Math.max(15, st.deliveries * 1.8))].map((val, idx) => (
|
||||
<div key={idx} className="flex-1 bg-zinc-100 rounded-t-sm h-full relative overflow-hidden group/bar">
|
||||
<div
|
||||
style={{ height: `${val}%` }}
|
||||
className={`absolute bottom-0 left-0 right-0 rounded-t-sm transition-all duration-500 ${
|
||||
st.status.toLowerCase() === 'active'
|
||||
? st.deliveries > 40
|
||||
? 'bg-rose-500/80 group-hover/bar:bg-rose-500'
|
||||
: 'bg-[#662582]/70 group-hover/bar:bg-[#662582]'
|
||||
: 'bg-amber-500/70 group-hover/bar:bg-amber-500'
|
||||
}`}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{/* Lead Manager Profile block */}
|
||||
<div className="flex justify-between items-center text-xs text-zinc-650 bg-zinc-50/80 rounded-xl p-2.5 border border-zinc-100/80 mt-4">
|
||||
@@ -567,22 +547,28 @@ export default function App() {
|
||||
};
|
||||
|
||||
// ── Auth gate ──────────────────────────────────────────────────────────────
|
||||
// Signed out → login screen. User role → their single allocated store console
|
||||
// (scoped by applocationid). Only the admin role reaches the full operations
|
||||
// dashboard with the all-stores registry below.
|
||||
if (authRole === null) {
|
||||
return <LoginView onLogin={handleLogin} />;
|
||||
}
|
||||
if (authRole === 'user' && authUser) {
|
||||
return <UserStorePage onLogout={handleLogout} user={authUser} />;
|
||||
return (
|
||||
<Routes>
|
||||
<Route path="/login" element={<LoginView onLogin={handleLogin} />} />
|
||||
<Route path="*" element={<Navigate to="/login" replace />} />
|
||||
</Routes>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-[#f8fafc] text-[#0f172a] font-sans antialiased">
|
||||
if (authRole === 'user' && authUser) {
|
||||
return (
|
||||
<Routes>
|
||||
<Route path="/store/*" element={<UserStorePage onLogout={handleLogout} user={authUser} />} />
|
||||
<Route path="*" element={<Navigate to="/store/console" replace />} />
|
||||
</Routes>
|
||||
);
|
||||
}
|
||||
|
||||
const AdminConsole = (
|
||||
<div className="min-h-screen bg-[#f8fafc] text-[#0f172a] font-sans antialiased overflow-x-hidden">
|
||||
{/* Navbar segment */}
|
||||
<Header
|
||||
currentSection={currentSection}
|
||||
setCurrentSection={handleSetSection}
|
||||
isCoimbatoreView={isCoimbatoreView}
|
||||
onToggleSidebar={() => setSidebarOpen((prev) => !prev)}
|
||||
isSidebarOpen={sidebarOpen}
|
||||
@@ -610,60 +596,69 @@ export default function App() {
|
||||
/>
|
||||
|
||||
{/* Main Container workspace layout splits */}
|
||||
<div className="flex pt-16">
|
||||
<div className="flex pt-16 w-full max-w-[100vw]">
|
||||
|
||||
{/* Interactive Left Rail */}
|
||||
<Sidebar
|
||||
currentSection={currentSection}
|
||||
setCurrentSection={handleSetSection}
|
||||
isCoimbatoreView={isCoimbatoreView}
|
||||
setIsCoimbatoreView={setIsCoimbatoreView}
|
||||
isOpen={sidebarOpen}
|
||||
isAdmin={authRole === 'admin'}
|
||||
onClose={() => setSidebarOpen(false)}
|
||||
/>
|
||||
|
||||
{/* Main core pages payload area */}
|
||||
<main className={`flex-1 min-w-0 transition-all duration-300 ${sidebarOpen ? 'md:pl-64' : 'md:pl-20'} ${currentSection === 'inventory' ? 'h-[calc(100vh-64px)] overflow-hidden' : 'min-h-[calc(100vh-64px)]'}`}>
|
||||
<div className={`w-full transition-all duration-300 ${currentSection === 'inventory' ? 'h-full p-4 md:p-6 overflow-hidden' : 'p-container-margin md:p-xl space-y-lg'}`}>
|
||||
{/* Nav content routing */}
|
||||
{currentSection === 'dashboard' && (
|
||||
selectedStore ? (
|
||||
renderStoresSection()
|
||||
) : (
|
||||
<div className="space-y-6">
|
||||
<DashboardView searchQuery={searchQuery} isCoimbatoreView={isCoimbatoreView} tenantId={tenantId} />
|
||||
<div>
|
||||
{renderStoresSection()}
|
||||
<Routes>
|
||||
<Route index element={<Navigate to="dashboard" replace />} />
|
||||
<Route path="dashboard" element={
|
||||
selectedStore ? (
|
||||
renderStoresSection()
|
||||
) : (
|
||||
<div className="space-y-6">
|
||||
<DashboardView searchQuery={searchQuery} isCoimbatoreView={isCoimbatoreView} tenantId={tenantId} />
|
||||
<div>
|
||||
{renderStoresSection()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
|
||||
{currentSection === 'inventory' && (
|
||||
<InventoryView
|
||||
searchQuery={searchQuery}
|
||||
isCoimbatoreView={isCoimbatoreView}
|
||||
tenantId={tenantId}
|
||||
/>
|
||||
)}
|
||||
|
||||
{currentSection === 'reports' && (
|
||||
<ReportsView
|
||||
searchQuery={searchQuery}
|
||||
isCoimbatoreView={isCoimbatoreView}
|
||||
setIsCoimbatoreView={setIsCoimbatoreView}
|
||||
tenantId={tenantId}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
||||
{/* Handle alternative sections: Settings */}
|
||||
{['settings'].includes(currentSection) &&
|
||||
renderSecondarySection()
|
||||
}
|
||||
)
|
||||
} />
|
||||
|
||||
<Route path="inventory" element={
|
||||
<InventoryView
|
||||
searchQuery={searchQuery}
|
||||
isCoimbatoreView={isCoimbatoreView}
|
||||
tenantId={tenantId}
|
||||
/>
|
||||
} />
|
||||
|
||||
<Route path="reports" element={
|
||||
<ReportsView
|
||||
searchQuery={searchQuery}
|
||||
isCoimbatoreView={isCoimbatoreView}
|
||||
setIsCoimbatoreView={setIsCoimbatoreView}
|
||||
tenantId={tenantId}
|
||||
/>
|
||||
} />
|
||||
|
||||
<Route path="settings" element={
|
||||
<SettingsView tenantId={tenantId} user={authUser ?? undefined} />
|
||||
} />
|
||||
|
||||
</Routes>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Routes>
|
||||
<Route path="/admin/*" element={AdminConsole} />
|
||||
<Route path="*" element={<Navigate to="/admin/dashboard" replace />} />
|
||||
</Routes>
|
||||
|
||||
{/* CALENDAR SCHEDULER DIALOG MODAL */}
|
||||
{showCalendarModal && (
|
||||
@@ -798,6 +793,6 @@ export default function App() {
|
||||
)}
|
||||
|
||||
<ComparisonModal />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user