diff --git a/app/dashboard/admin/page.tsx b/app/dashboard/admin/page.tsx index d3fbe10..8bde25a 100644 --- a/app/dashboard/admin/page.tsx +++ b/app/dashboard/admin/page.tsx @@ -16,7 +16,7 @@ export default function AdminPage() {

Restricted area. Only admin1 can access.

-
+
diff --git a/app/dashboard/admin/status/page.tsx b/app/dashboard/admin/status/page.tsx index 5f26c91..618e143 100644 --- a/app/dashboard/admin/status/page.tsx +++ b/app/dashboard/admin/status/page.tsx @@ -74,7 +74,7 @@ export default async function AdminStatusPage() {

Monitor system health and performance metrics

-
+
{/* Server Status */} diff --git a/app/dashboard/analytics/loading.tsx b/app/dashboard/analytics/loading.tsx index 7dee90c..a2943cb 100644 --- a/app/dashboard/analytics/loading.tsx +++ b/app/dashboard/analytics/loading.tsx @@ -12,7 +12,7 @@ export default function AnalyticsLoading() {
{/* Metrics Cards */} -
+
{[...Array(4)].map((_, i) => ( diff --git a/app/dashboard/categories/page.tsx b/app/dashboard/categories/page.tsx index a7d8f17..0bf0216 100644 --- a/app/dashboard/categories/page.tsx +++ b/app/dashboard/categories/page.tsx @@ -353,7 +353,7 @@ export default function CategoriesPage() {
-
+
{/* Add Category Card - Takes up 2 columns */} diff --git a/app/dashboard/chats/layout.tsx b/app/dashboard/chats/layout.tsx index 51463be..0f8ffc8 100644 --- a/app/dashboard/chats/layout.tsx +++ b/app/dashboard/chats/layout.tsx @@ -8,8 +8,9 @@ export const metadata: Metadata = { export const viewport: Viewport = { width: "device-width", initialScale: 1, - maximumScale: 5, + maximumScale: 3, userScalable: true, + viewportFit: "cover", themeColor: [ { media: "(prefers-color-scheme: dark)", color: "#000000" }, { media: "(prefers-color-scheme: light)", color: "#D53F8C" }, diff --git a/app/dashboard/loading.tsx b/app/dashboard/loading.tsx index 5f9f15a..bb6a1eb 100644 --- a/app/dashboard/loading.tsx +++ b/app/dashboard/loading.tsx @@ -16,7 +16,7 @@ export default function DashboardLoading() {
{/* Order statistics skeletons */} -
+
{[...Array(4)].map((_, i) => ( diff --git a/app/dashboard/page.tsx b/app/dashboard/page.tsx index 932b90d..35d44fa 100644 --- a/app/dashboard/page.tsx +++ b/app/dashboard/page.tsx @@ -25,7 +25,7 @@ function DashboardContentSkeleton() {
{/* Stats cards skeleton */} -
+
{[...Array(4)].map((_, i) => ( diff --git a/app/dashboard/products/page.tsx b/app/dashboard/products/page.tsx index 6b9c437..bf2237a 100644 --- a/app/dashboard/products/page.tsx +++ b/app/dashboard/products/page.tsx @@ -386,18 +386,18 @@ export default function ProductsPage() { return (
-
+

Products

-
+
setSearchTerm(e.target.value)} /> @@ -412,18 +412,22 @@ export default function ProductsPage() { )}
- - +
+ + +
diff --git a/app/dashboard/storefront/page.tsx b/app/dashboard/storefront/page.tsx index c46ae64..6eb9bda 100644 --- a/app/dashboard/storefront/page.tsx +++ b/app/dashboard/storefront/page.tsx @@ -220,7 +220,7 @@ export default function StorefrontPage() {
-
+
{/* Security Settings */}
diff --git a/app/globals.css b/app/globals.css index f1c9426..9f182d9 100644 --- a/app/globals.css +++ b/app/globals.css @@ -90,6 +90,154 @@ body { background-color: hsl(var(--primary) / 0.9); } + /* Chromebook-specific optimizations */ + @media screen and (max-width: 1366px) and (min-resolution: 1.5dppx) { + /* Chromebook display optimizations */ + .text-sm { + font-size: 0.875rem; + line-height: 1.25rem; + } + + .text-base { + font-size: 1rem; + line-height: 1.5rem; + } + + /* Better touch targets for Chromebooks */ + button, input, textarea, [role="button"], [role="tab"] { + min-height: 48px; + min-width: 48px; + } + + /* Improved spacing for Chromebook screens */ + .space-y-2 > * + * { + margin-top: 0.75rem; + } + + .space-y-4 > * + * { + margin-top: 1.25rem; + } + } + + /* Chromebook touch screen optimizations */ + @media (pointer: coarse) and (hover: none) { + /* Larger touch targets */ + .touch-target { + min-height: 52px; + min-width: 52px; + } + + /* Better spacing for touch interactions */ + .space-y-2 > * + * { + margin-top: 1rem; + } + + /* Improved button padding */ + button { + padding: 0.75rem 1rem; + } + + /* Better input field sizing */ + input, textarea { + padding: 0.875rem; + font-size: 1rem; + } + + /* Enhanced focus states for touch */ + button:focus-visible, input:focus-visible, textarea:focus-visible { + outline: 3px solid hsl(var(--ring)); + outline-offset: 2px; + } + } + + /* Chromebook keyboard navigation improvements */ + @media (hover: hover) and (pointer: fine) { + /* Better hover states for mouse/trackpad */ + button:hover:not(:disabled) { + transform: translateY(-1px); + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + } + + /* Improved focus indicators */ + button:focus-visible, input:focus-visible, textarea:focus-visible { + outline: 2px solid hsl(var(--ring)); + outline-offset: 2px; + box-shadow: 0 0 0 4px hsl(var(--ring) / 0.2); + } + } + + /* Chromebook display scaling fixes */ + @media screen and (min-resolution: 1.5dppx) { + /* Prevent text from being too small on high-DPI displays */ + html { + -webkit-text-size-adjust: 100%; + text-size-adjust: 100%; + } + + /* Better font rendering */ + body { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + } + } + + /* Chromebook scrolling improvements */ + .overflow-y-auto { + -webkit-overflow-scrolling: touch; + scroll-behavior: smooth; + /* Better momentum scrolling for Chromebooks */ + overscroll-behavior: contain; + } + + /* Chromebook chat interface optimizations */ + .chat-message { + /* Better message bubble sizing for touch */ + min-height: 44px; + padding: 0.75rem; + } + + /* Chromebook form optimizations */ + .form-input { + /* Better input field sizing for Chromebooks */ + min-height: 48px; + font-size: 1rem; + padding: 0.75rem 1rem; + } + + /* Chromebook button optimizations */ + .btn-chromebook { + min-height: 48px; + min-width: 48px; + padding: 0.75rem 1rem; + font-size: 1rem; + border-radius: 0.5rem; + } + + /* Enhanced keyboard focus indicators for Chromebooks */ + .keyboard-focus { + outline: 3px solid hsl(var(--ring)); + outline-offset: 2px; + box-shadow: 0 0 0 4px hsl(var(--ring) / 0.3); + } + + /* Better focus management for Chromebook keyboard navigation */ + button:focus-visible, + input:focus-visible, + textarea:focus-visible, + [role="button"]:focus-visible, + [role="tab"]:focus-visible { + outline: 3px solid hsl(var(--ring)); + outline-offset: 2px; + box-shadow: 0 0 0 4px hsl(var(--ring) / 0.3); + } + + /* Chromebook-specific focus ring */ + @media (prefers-reduced-motion: no-preference) { + .keyboard-focus { + transition: outline 0.2s ease, box-shadow 0.2s ease; + } + } + .bg-muted { background-color: hsl(var(--muted) / 0.8); } diff --git a/app/layout.tsx b/app/layout.tsx index e0ddcd9..d2017bf 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -55,8 +55,9 @@ export const metadata: Metadata = { export const viewport: Viewport = { width: "device-width", initialScale: 1, - maximumScale: 5, + maximumScale: 3, userScalable: true, + viewportFit: "cover", themeColor: [ { media: "(prefers-color-scheme: dark)", color: "#000000" }, { media: "(prefers-color-scheme: light)", color: "#D53F8C" }, diff --git a/components/admin/AdminAnalytics.tsx b/components/admin/AdminAnalytics.tsx index 49a2832..0fc866a 100644 --- a/components/admin/AdminAnalytics.tsx +++ b/components/admin/AdminAnalytics.tsx @@ -240,7 +240,7 @@ export default function AdminAnalytics() {
-
+
{/* Orders Card */} diff --git a/components/analytics/AnalyticsDashboard.tsx b/components/analytics/AnalyticsDashboard.tsx index 428c9de..a97ed69 100644 --- a/components/analytics/AnalyticsDashboard.tsx +++ b/components/analytics/AnalyticsDashboard.tsx @@ -196,7 +196,7 @@ export default function AnalyticsDashboard({ initialData }: AnalyticsDashboardPr
{/* Key Metrics Cards */} -
+
{isLoading ? ( [...Array(4)].map((_, i) => ( @@ -272,7 +272,7 @@ export default function AnalyticsDashboard({ initialData }: AnalyticsDashboardPr {/* Analytics Tabs */}
- + Revenue diff --git a/components/analytics/AnalyticsDashboardSkeleton.tsx b/components/analytics/AnalyticsDashboardSkeleton.tsx index 20fdefe..ea4e8ad 100644 --- a/components/analytics/AnalyticsDashboardSkeleton.tsx +++ b/components/analytics/AnalyticsDashboardSkeleton.tsx @@ -14,7 +14,7 @@ export default function AnalyticsDashboardSkeleton() { return (
{/* Key Metrics Cards */} -
+
{[...Array(4)].map((_, i) => ( ))} diff --git a/components/analytics/ProfitAnalyticsChart.tsx b/components/analytics/ProfitAnalyticsChart.tsx index 30889cc..eeacd19 100644 --- a/components/analytics/ProfitAnalyticsChart.tsx +++ b/components/analytics/ProfitAnalyticsChart.tsx @@ -77,7 +77,7 @@ export default function ProfitAnalyticsChart({ timeRange, hideNumbers = false }:
{/* Summary Cards Skeleton */} -
+
{[...Array(4)].map((_, i) => ( @@ -197,7 +197,7 @@ export default function ProfitAnalyticsChart({ timeRange, hideNumbers = false }: return (
{/* Summary Cards */} -
+
Revenue (Tracked) diff --git a/components/dashboard/ChatDetail.tsx b/components/dashboard/ChatDetail.tsx index 3637a02..6a9b602 100644 --- a/components/dashboard/ChatDetail.tsx +++ b/components/dashboard/ChatDetail.tsx @@ -15,6 +15,8 @@ import { getCookie, clientFetch } from "@/lib/api"; import { ImageViewerModal } from "@/components/modals/image-viewer-modal"; import BuyerOrderInfo from "./BuyerOrderInfo"; import { useIsTouchDevice } from "@/hooks/use-mobile"; +import { useChromebookScroll, useSmoothScrollToBottom } from "@/hooks/use-chromebook-scroll"; +import { useChromebookKeyboard, useChatFocus } from "@/hooks/use-chromebook-keyboard"; interface Message { _id: string; @@ -100,10 +102,18 @@ export default function ChatDetail({ chatId }: { chatId: string }) { const [selectedAttachmentIndex, setSelectedAttachmentIndex] = useState(null); const seenMessageIdsRef = useRef>(new Set()); const isTouchDevice = useIsTouchDevice(); + const scrollContainerRef = useChromebookScroll(); + const { scrollToBottom, scrollToBottomInstant } = useSmoothScrollToBottom(); + useChromebookKeyboard(); + const { focusMessageInput, focusNextMessage, focusPreviousMessage } = useChatFocus(); // Scroll to bottom utility functions - const scrollToBottom = () => { - messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }); + const scrollToBottomHandler = () => { + if (scrollContainerRef.current) { + scrollToBottom(scrollContainerRef.current); + } else { + messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }); + } }; const isNearBottom = () => { @@ -262,7 +272,7 @@ export default function ChatDetail({ chatId }: { chatId: string }) { // Scroll to bottom on initial load setTimeout(() => { - scrollToBottom(); + scrollToBottomHandler(); }, 100); } catch (error) { console.error("Error fetching chat data:", error); @@ -363,13 +373,33 @@ export default function ChatDetail({ chatId }: { chatId: string }) { } else if (e.key === 'Escape') { // Clear the input on Escape setMessage(''); + focusMessageInput(); } else if (e.key === 'ArrowUp' && message === '') { // Load previous message on Arrow Up when input is empty e.preventDefault(); const lastVendorMessage = [...messages].reverse().find(msg => msg.sender === 'vendor'); if (lastVendorMessage) { setMessage(lastVendorMessage.content); + } else { + focusPreviousMessage(); } + } else if (e.key === 'ArrowDown' && message === '') { + // Focus next message + e.preventDefault(); + focusNextMessage(); + } else if (e.key === 'Tab') { + // Enhanced tab navigation for Chromebooks + e.preventDefault(); + const focusableElements = document.querySelectorAll( + 'button:not([disabled]), input:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])' + ) as NodeListOf; + + const currentIndex = Array.from(focusableElements).indexOf(document.activeElement as HTMLElement); + const nextIndex = e.shiftKey + ? (currentIndex > 0 ? currentIndex - 1 : focusableElements.length - 1) + : (currentIndex < focusableElements.length - 1 ? currentIndex + 1 : 0); + + focusableElements[nextIndex]?.focus(); } }; @@ -601,11 +631,19 @@ export default function ChatDetail({ chatId }: { chatId: string }) {
{chat.messages.length === 0 ? (
@@ -624,7 +662,8 @@ export default function ChatDetail({ chatId }: { chatId: string }) { >
diff --git a/components/dashboard/content.tsx b/components/dashboard/content.tsx index b06ab8d..7c8ba0e 100644 --- a/components/dashboard/content.tsx +++ b/components/dashboard/content.tsx @@ -80,7 +80,7 @@ export default function Content({ username, orderStats }: ContentProps) {
{/* Order Statistics */} -
+
{statsConfig.map((stat) => ( +
{[...Array(itemsCount)].map((_, i) => ( diff --git a/components/layout/sidebar.tsx b/components/layout/sidebar.tsx index 9b7222e..74df865 100644 --- a/components/layout/sidebar.tsx +++ b/components/layout/sidebar.tsx @@ -60,7 +60,7 @@ const Sidebar: React.FC = () => {