diff --git a/src/components/buttons/Button.tsx b/src/components/buttons/Button.tsx index a7fda27..81594ea 100644 --- a/src/components/buttons/Button.tsx +++ b/src/components/buttons/Button.tsx @@ -1,7 +1,8 @@ import type { ButtonHTMLAttributes, ReactNode } from 'react'; import { cn } from '../../lib/cn'; +import './style.css' -export type ButtonVariant = 'primary' | 'navy' | 'secondary' | 'ghost' | 'danger'; +export type ButtonVariant = 'primary' | 'navy' | 'secondary' | 'ghost' | 'danger'|'outline'; export type ButtonSize = 'sm' | 'md' | 'lg'; export interface ButtonProps extends ButtonHTMLAttributes { @@ -22,11 +23,12 @@ const SIZES: Record = { }; const VARIANTS: Record = { - primary: 'bg-sunrise text-white border border-transparent shadow-sunrise', + primary: 'z-btn border border-transparent shadow-blue-600/30', navy: 'bg-navy-900 text-on-navy border border-transparent shadow-sm', secondary: 'bg-card text-strong border border-border-default shadow-xs', ghost: 'bg-transparent text-body border border-transparent', danger: 'bg-ruby-600 text-white border border-transparent shadow-sm', + outline:'z-btn-outline' }; /** diff --git a/src/components/buttons/style.css b/src/components/buttons/style.css new file mode 100644 index 0000000..9af2bfc --- /dev/null +++ b/src/components/buttons/style.css @@ -0,0 +1,45 @@ +.z-btn { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 6px; + padding: 8px 16px; + border-radius: var(--z-border-radius-md); + font-size: var(--z-font-sm); + font-weight: 500; + font-family: inherit; + cursor: pointer; + transition: all 0.2s ease; + text-decoration: none; + line-height: 1.4; + background: var(--z-btn-primary-bg); + color: #ffffff; +} + +.z-btn-primary { + border: none; +} + +.z-btn:hover { + background: var(--primary-btn-active); +} + +.z-btn-secondary { + background-color: var(--z-block-bg); + color: var(--z-text-primary); + border: 1px solid var(--z-block-border); +} + +.z-btn-secondary:hover { + background-color: var(--z-body-bg); +} + +.z-btn-outline { + background: transparent; + color: var(--z-btn-outline-color); + border: 1px solid var(--z-btn-outline-border); +} + +.z-btn-outline:hover { + background-color: var(--z-color-primary-light); +} \ No newline at end of file diff --git a/src/components/cards/OrderCard.tsx b/src/components/cards/OrderCard.tsx index 2aad9c5..b53d507 100644 --- a/src/components/cards/OrderCard.tsx +++ b/src/components/cards/OrderCard.tsx @@ -28,14 +28,14 @@ export function OrderCard({ row, fields }: { row: Record; fields: a const gridVal = Array.isArray(gridValRaw) ? gridValRaw : []; return ( -
+
{/* Top Header Section */} -
+
Order ID - {orderIdStr} + {orderIdStr}
{isProductive && } @@ -46,11 +46,11 @@ export function OrderCard({ row, fields }: { row: Record; fields: a
Date - {dateVal} + {dateVal}
Store & Route - + {storeVal} ({routeVal})
@@ -58,25 +58,25 @@ export function OrderCard({ row, fields }: { row: Record; fields: a
{/* Middle Section: Distributor & User */} -
+
-
+
Distributor - {distributorVal} + {distributorVal}
-
+
Placed by - {userVal} + {userVal}
-
+
@@ -84,11 +84,11 @@ export function OrderCard({ row, fields }: { row: Record; fields: a {/* Bottom Section: Order Items */} {gridVal.length > 0 && ( -
+
-

+

Order Items - + {gridVal.length}

@@ -101,19 +101,19 @@ export function OrderCard({ row, fields }: { row: Record; fields: a const bags = formatValue(item.bags || item.total_bags || item.quantity || 0); return ( -
+
- + {sku}
- + {productName}
- + {bags} diff --git a/src/screens/ConsoleLayout.tsx b/src/screens/ConsoleLayout.tsx index 25a2c76..7a84bbc 100644 --- a/src/screens/ConsoleLayout.tsx +++ b/src/screens/ConsoleLayout.tsx @@ -1,43 +1,20 @@ import { useEffect, useState } from 'react'; import { NavLink, Navigate, Outlet, useNavigate } from 'react-router-dom'; -import { LogOut, Sun, Moon } from 'lucide-react'; +import { LogOut, Menu, X } from 'lucide-react'; import { cn } from '../lib/cn'; import { useAuth } from '../auth/context'; import { onAuthErrorAll, orderBookingClient } from '../api/clients'; import { APP_ID } from '../api/config'; import { SCREENS } from './tabs'; +import './screen.css'; /** Auth-guarded shell: slim navy top bar + fixed bottom tab nav + routed . */ export function ConsoleLayout() { const { authed, logout } = useAuth(); const navigate = useNavigate(); const user = orderBookingClient.currentUser(); - - const [isDark, setIsDark] = useState(() => document.documentElement.classList.contains('dark')); - useEffect(() => { - const saved = localStorage.getItem('theme'); - const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; - if (saved === 'dark' || (!saved && prefersDark)) { - document.documentElement.classList.add('dark'); - setIsDark(true); - } else { - document.documentElement.classList.remove('dark'); - setIsDark(false); - } - }, []); - - const toggleTheme = () => { - if (isDark) { - document.documentElement.classList.remove('dark'); - localStorage.setItem('theme', 'light'); - setIsDark(false); - } else { - document.documentElement.classList.add('dark'); - localStorage.setItem('theme', 'dark'); - setIsDark(true); - } - }; + const [isMenuOpen, setIsMenuOpen] = useState(false); // A 401 from any workflow client bounces back to login. useEffect(() => { @@ -51,33 +28,20 @@ export function ConsoleLayout() { return (
-
-
- Krishna Sales - Sandbox {APP_ID}{user?.name ? ` · ${user.name}` : ''} -
- -
+
+
- - +
+ Krishna Sales + {/* Sandbox {APP_ID}{user?.name ? ` · ${user.name}` : ''} */} +
@@ -123,6 +87,74 @@ export function ConsoleLayout() { ); })} + + {/* Sidebar Overlay */} + {isMenuOpen && ( +
setIsMenuOpen(false)} + /> + )} + + {/* Sidebar */} +
+
+ Krishna Field Sales + +
+
+ {SCREENS.map((t) => { + const Icon = t.icon; + return ( + setIsMenuOpen(false)} + className={({ isActive }) => cn( + "flex items-center gap-3 px-4 py-3 mx-2 rounded-lg no-underline transition-colors duration-150 sidebar-item", + isActive ? "active" : "" + )} + > + + {t.label} + + ); + })} +
+ +
+ {user && ( +
+ + {user.name || 'User'} + {user.email || 'user@email.com'} +
+ )} + +
+
); } diff --git a/src/screens/OrdersPage.tsx b/src/screens/OrdersPage.tsx index 3f85b3a..d890a99 100644 --- a/src/screens/OrdersPage.tsx +++ b/src/screens/OrdersPage.tsx @@ -19,14 +19,14 @@ export function OrdersPage() { return ( <> - { const id = row.instance_id as number | string | undefined; if (id != null) navigate(`/orders/${id}`); - }} + }} headerActions={ - } @@ -38,8 +38,8 @@ export function OrdersPage() { title="Place Order" width="md" > - { setIsCreating(false); diff --git a/src/screens/screen.css b/src/screens/screen.css new file mode 100644 index 0000000..12a32fd --- /dev/null +++ b/src/screens/screen.css @@ -0,0 +1,20 @@ +/* nav bar */ +.top-navbar { + background: var(--nav-bg-color); +} + +.nav-menu-icon, +.nav-title { + color: var(--nav-item-color) +} + +.sidebar-menu-icon, +.sidebar-item { + color: var(--nav-item-color); +} + +.sidebar-menu-icon-active, +.sidebar-item.active { + color: var(--nav-item-active); + background: var(--nav-item-active-bg); +} \ No newline at end of file diff --git a/src/styles/styles.css b/src/styles/styles.css index 9230be8..32a9668 100644 --- a/src/styles/styles.css +++ b/src/styles/styles.css @@ -7,8 +7,8 @@ (Referenced from the lead-to-policy console.) ============================================================ */ @import url('https://fonts.googleapis.com/css2?family=Inter:opsz,wght@14..32,400;14..32,500;14..32,600;14..32,700;14..32,800&family=Inter+Tight:wght@500;600;700;800&display=swap'); +@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&display=swap'); @import 'tailwindcss'; -@custom-variant dark (&:where(.dark, .dark *)); @import './tokens/colors.css'; @import './tokens/typography.css'; @import './tokens/spacing.css'; @@ -121,58 +121,388 @@ html { height: 100%; } + body, #root { min-height: 100%; } + body { margin: 0; font-family: var(--font-sans); - background: var(--surface-app); - color: var(--text-body); + background: var(--body-bg); + color: var(--font-color); -webkit-font-smoothing: antialiased; } } @layer components { + /* Brand gradients — not expressible as plain utilities. */ .bg-sunrise { background-image: var(--gradient-sunrise); } + .bg-sunrise-soft { background-image: var(--gradient-sunrise-soft); } + .bg-navy-grad { background-image: var(--gradient-navy); } + /* Tabular figures for aligning currency & counts. */ .nums { font-variant-numeric: tabular-nums; } + /* Sunrise focus ring on inputs/selects. */ .focus-ring:focus-within { border-color: var(--sunrise-500); box-shadow: var(--shadow-focus); } + /* Slim, theme-tinted scrollbar for in-panel scroll areas. */ .scrollbar-slim { scrollbar-width: thin; scrollbar-color: var(--border-default) transparent; } + .scrollbar-slim::-webkit-scrollbar { width: 10px; height: 10px; } + .scrollbar-slim::-webkit-scrollbar-track { background: transparent; } + .scrollbar-slim::-webkit-scrollbar-thumb { background-color: var(--border-default); background-clip: padding-box; border: 3px solid transparent; border-radius: 9999px; } + .scrollbar-slim:hover::-webkit-scrollbar-thumb { background-color: var(--text-faint); } } + +/* root variable */ + +:root { + --primary-color: #0058be; + --secondary-color: #f9fafb; + --font-color: #10182b; + --font-family: "IBM Plex Sans", serif; + --light-font-color: #667085; + --body-bg: #f0f4f8; + --bg-plain: #fff; + --bg-active: #00000014; + --border: #e5e7eb; + --shadow: 0px 4px 8px 0px rgba(228, 231, 236, 0.3); + --hover: #e4e4e4; + --hover-font: #fff; + --hover-bg: #f9fafb; + --hover-border: #667085; + --menu-item-bg: rgba(255, 255, 255, 0.1); + + + /* Navbar background color */ + --nav-bg-color: #fff; + --nav-item-color: #10182b; + --nav-item-active: #1b84ff; + --nav-item-active-bg: #c0d4ed45; + --nav-item-border-bottom: transparent; + --nav-dropdown-bg: #fff; + + /* Matching the navbar color */ + --nav-dropdown-color: #4B5675; + --nav-dropdown-active: #2e56e1; + --nav-dropdown-active-bg: #F9F9F9; + --nav-dropdown-border: none; + --nav-dropdown-radius: 4px; + --nav-dropdown-padding: 10px; + --menu-item-radius: 4px; + --p-8: 0px; + --nav-border: rgba(255, 255, 255, 0.1); + --nav-left-separator-line: #484848; + + /* tiles card */ + --tiles-card-bg: #fff; + --tiles-card-border: #e5e7eb; + --tiles-font-color: #10182b; + --tiles-font-size: 16px; + --tiles-count-size: 20px; + + /* button */ + --z-btn-primary-bg: #0058be; + --z-btn-primary-color: #fff; + --primary-btn-active: #196ed0; + --primary-btn-activeClr: #fff; + --z-btn-secondary-bg: #f4f4f4; + --z-btn-secondary-color: #10182b; + --secondary-btn-active-bg: #eaeaea; + --z-btn-outline-color: #0058be; + --z-btn-outline-border: #0058be; + + --button-height: 36px; + --z-btn-sm-height: 32px; + --z-btn-md-height: 40px; + --z-btn-lg-height: 48px; + + /* blocks */ + --block-bg: #fff; + --block-padding: 20px; + --block-radius: 20px; + --block-border: #e5e7eb; + --block-shadow: 0px 4px 8px 0px rgba(228, 231, 236, 0.3); + + /* button or input */ + --button-radius: 8px; + --input-shadow: 0px 4px 8px 0px rgba(228, 231, 236, 0.3); + --input-border: #e5e7eb; + + /* font-size */ + --small-font: 14px; + --medium-font: 16px; + --large-font: 20px; + --z-btn-font-sm: 12px; + --z-btn-font-md: 14px; + --z-btn-font-lg: 16px; + + --small-icon: 24px; + + /* record view table color */ + --rv-table-bg: #fff; + --rv-table-header: #f9fafb; + --table-row-bg-select: #fafafa; + --table-tr-active: #f9fafb; + --rv-table-height: 40px; + --rv-table-btn-height: 36px; + --table-td-padding: 8px 20px; + + /* form input tags */ + --form-input-height: 40px; + --form-bg: #fff; + --form-input-bg: #fff; + --inputBox-border: ##e5e7eb; + --inputBox-border-active: #a2acbf; + --disable-bg: #fafafa; + --disable-color: #98a2b3; + + --toolTip-color: #2185d0; + --toolTip-active-clr: #208fe3; + + /* new template style variables */ + --z-body-bg: #f0f4f8; + --z-bg-plain: #fff; + + --z-bg-primary: #0058be; + --z-bg-secondary: #f4f4f4; + --z-bg-success: #1fc16b; + --z-bg-error: #fa3748; + --z-bg-light: #ffffff; + --z-bg-dark: #1e2227; + + --z-text-default: #10182b; + --z-text-primary: #0058be; + --z-text-secondary: #6c757d; + --z-text-success: #fff; + --z-text-error: #fff; + --z-text-muted: #6c757d; + --z-text-inverse: #ffffff; + --z-text-plain: #fff; + + + --z-bg-active: #3d94fb; + + --z-border-primary: #0058be; + --z-border-secondary: #ced4da; + --z-border-success: #1fc16b; + --z-border-error: #fa3748; + + --z-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05); + --z-shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1); + --z-shadow-lg: 0 10px 20px rgba(0, 0, 0, 0.15); + + --z-font-size-xs: 8px; + --z-font-size-sm: 12px; + --z-font-size-md: 14px; + --z-font-size-lg: 16px; + --z-font-size-xl: 20px; + + --z-border-size-sm: 1px; + --z-border-size-md: 2px; + --z-border-size-lg: 4px; + + --z-border-radius-sm: 4px; + --z-border-radius-md: 8px; + --z-border-radius-lg: 16px; + --z-border-radius-full: 50%; + --z-border-radius-pill: 30px; + + /* app default text */ + --z-font-sm: 14px; + --z-font-md: 16px; + --z-font-lg: 20px; + + /* button style */ + --z-btn-radius: 8px; + --z-btn-height: 44px; + + /* block and section styles */ + --z-block-bg: #fff; + --z-block-radius: 8px; + --z-block-border: #e5e7eb; + --z-block-shadow: box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); + + /* record view table */ + --z-rv-table-header: #fff; + --z-rv-td-padding: 8px 20px; + --z-rv-table-border: #e5e7eb; + --z-rv-td-height: 40px; + + --z-tile-bg: #fff; + --z-tile-border: #e5e7eb; + + /*-----------------New BG Color Palatte----------------*/ + + /* Primary Colors */ + --z-bg-primary-100: #c0d4ed; + --z-bg-primary-200: #83b6f4; + --z-bg-primary-300: #5aa2f8; + --z-bg-primary-400: #0058be; + + /* Secondary Colors */ + --z-bg-secondary-100: #ffce8d; + --z-bg-secondary-200: #ffbb62; + --z-bg-secondary-300: #faa73b; + --z-bg-secondary-400: #f5f6f7; + + /* Gradient Colors */ + --z-bg-gradient-1: linear-gradient(90deg, #0058be 0%, #104F99 100%); + --z-bg-gradient-2: linear-gradient(90deg, #1C38A7 0%, #2E55DF 100%); + --z-bg-gradient-3: linear-gradient(94.13deg, #83B6F4 2.64%, #2B6BBA 97.36%); + --z-bg-gradient-4: linear-gradient(99.74deg, #A0C5F4 4.16%, #EFF3F8 97.03%); + + /* Neutral Colors */ + --z-bg-neutral-100: #ffffff; + --z-bg-neutral-200: #f9fafb; + --z-bg-neutral-300: #e5e7eb; + --z-bg-neutral-400: #d0d5dd; + --z-bg-neutral-500: #98a2b3; + --z-bg-neutral-600: #667085; + --z-bg-neutral-700: #475467; + --z-bg-neutral-800: #1d2939; + --z-bg-neutral-900: #10182b; + --z-bg-neutral-1000: #0c1323; + + /* Danger Colors */ + --z-bg-danger-100: #fecdca; + --z-bg-danger-200: #fda29b; + --z-bg-danger-300: #f97066; + --z-bg-danger-400: #f04438; + + /* Warning Colors */ + --z-bg-warning-100: #ffdf89; + --z-bg-warning-200: #fec84b; + --z-bg-warning-300: #ffdb43; + --z-bg-warning-400: #dfb400; + + /* Success Colors */ + --z-bg-success-100: #a6f4c5; + --z-bg-success-200: #6ce9a6; + --z-bg-success-300: #32d584; + --z-bg-success-400: #12b76a; + + /*-----------------New Text Color Palatte----------------*/ + + /* Primary Colors */ + --z-text-primary-100: #c0d4ed; + --z-text-primary-200: #83b6f4; + --z-text-primary-300: #5aa2f8; + --z-text-primary-400: #0058be; + + /* Secondary Colors */ + --z-text-secondary-100: #ffce8d; + --z-text-secondary-200: #ffbb62; + --z-text-secondary-300: #faa73b; + --z-text-secondary-400: #f79009; + + /* Neutral Colors */ + --z-text-neutral-100: #ffffff; + --z-text-neutral-200: #f9fafb; + --z-text-neutral-300: #e5e7eb; + --z-text-neutral-400: #d0d5dd; + --z-text-neutral-500: #98a2b3; + --z-text-neutral-600: #667085; + --z-text-neutral-700: #475467; + --z-text-neutral-800: #1d2939; + --z-text-neutral-900: #10182b; + --z-text-neutral-1000: #0c1323; + + /* Danger Colors */ + --z-text-danger-100: #fecdca; + --z-text-danger-200: #fda29b; + --z-text-danger-300: #f97066; + --z-text-danger-400: #f04438; + + /* Warning Colors */ + --z-text-warning-100: #ffdf89; + --z-text-warning-200: #fec84b; + --z-text-warning-300: #ffdb43; + --z-text-warning-400: #dfb400; + + /* Success Colors */ + --z-text-success-100: #a6f4c5; + --z-text-success-200: #6ce9a6; + --z-text-success-300: #32d584; + --z-text-success-400: #12b76a; + + /*-----------------New Border Color Palatte----------------*/ + + /* Primary Colors */ + --z-border-default: #e5e7eb; + --z-border-primary-100: #c0d4ed; + --z-border-primary-200: #83b6f4; + --z-border-primary-300: #5aa2f8; + --z-border-primary-400: #0058be; + + /* Secondary Colors */ + --z-border-secondary-100: #ffce8d; + --z-border-secondary-200: #f3cfc4; + --z-border-secondary-300: #ebaf9d; + --z-border-secondary-400: #f79009; + + /* Neutral Colors */ + --z-border-neutral-100: #ffffff; + --z-border-neutral-200: #f9fafb; + --z-border-neutral-300: #e5e7eb; + --z-border-neutral-400: #d0d5dd; + --z-border-neutral-500: #98a2b3; + --z-border-neutral-600: #667085; + --z-border-neutral-700: #475467; + --z-border-neutral-800: #1d2939; + --z-border-neutral-900: #10182b; + --z-border-neutral-1000: #0c1323; + + /* Danger Colors */ + --z-border-danger-100: #fecdca; + --z-border-danger-200: #fda29b; + --z-border-danger-300: #f97066; + --z-border-danger-400: #f04438; + + /* Warning Colors */ + --z-border-warning-100: #ffdf89; + --z-border-warning-200: #fec84b; + --z-border-warning-300: #ffdb43; + --z-border-warning-400: #dfb400; + + /* Success Colors */ + --z-border-success-100: #a6f4c5; + --z-border-success-200: #6ce9a6; + --z-border-success-300: #32d584; + --z-border-success-400: #12b76a; +} \ No newline at end of file