diff --git a/dev-dist/sw.js b/dev-dist/sw.js index e42ad19..ae3c97b 100644 --- a/dev-dist/sw.js +++ b/dev-dist/sw.js @@ -79,7 +79,7 @@ define(['./workbox-21a80088'], (function (workbox) { 'use strict'; */ workbox.precacheAndRoute([{ "url": "index.html", - "revision": "0.dkv277t7u3k" + "revision": "0.9ku5uov2tfg" }], {}); workbox.cleanupOutdatedCaches(); workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), { diff --git a/public/print.css b/public/print.css index a408f81..02b8a48 100644 --- a/public/print.css +++ b/public/print.css @@ -1,5 +1,5 @@ - @media print { + /* Reset margins and hide unnecessary elements */ * { -webkit-print-color-adjust: exact !important; @@ -13,6 +13,7 @@ color: black !important; background: white !important; } + .bg-gradient-to-br { background-image: none !important; } @@ -164,11 +165,15 @@ } /* Ensure proper spacing */ - .space-y-4 > * + * { + .space-y-6>*+* { + margin-top: 18pt !important; + } + + .space-y-4>*+* { margin-top: 12pt !important; } - .space-y-2 > * + * { + .space-y-2>*+* { margin-top: 6pt !important; } @@ -186,4 +191,4 @@ background: transparent !important; background-color: transparent !important; } -} +} \ No newline at end of file diff --git a/public/pwa.css b/public/pwa.css index bfcb311..b020bce 100644 --- a/public/pwa.css +++ b/public/pwa.css @@ -51,6 +51,7 @@ button, /* Landscape mode optimizations */ @media (orientation: landscape) and (max-height: 500px) { + /* Compact header for landscape mobile */ header { height: 48px; @@ -65,6 +66,7 @@ button, /* Standalone mode specific styles (when app is installed) */ @media (display-mode: standalone) { + /* Add subtle indication that app is installed */ body::before { content: ""; @@ -90,10 +92,11 @@ body { /* Improve button touch targets on mobile */ @media (max-width: 768px) { - button:not(.icon-only) { - min-height: 44px; - padding: 0.75rem 1rem; - } + /* button:not(.icon-only) { */ + /* min-height: 44px; */ + /* min-width: 44px; */ + /* padding: 0.75rem 1rem; */ + /* } */ /* Larger tap targets for icon buttons */ button.icon-only { @@ -108,9 +111,12 @@ body { } @keyframes pulse { - 0%, 100% { + + 0%, + 100% { opacity: 1; } + 50% { opacity: 0.5; } @@ -134,6 +140,7 @@ body { /* iOS specific fixes */ @supports (-webkit-touch-callout: none) { + /* Fix iOS safari bounce */ body { position: fixed; @@ -193,9 +200,10 @@ body { /* Android specific fixes */ @media (max-width: 768px) { + /* Prevent address bar from covering content */ .mobile-viewport { min-height: 100vh; min-height: -webkit-fill-available; } -} +} \ No newline at end of file diff --git a/src/components/ArchiveEditDialog.tsx b/src/components/ArchiveEditDialog.tsx index 38ce391..ee7ee68 100644 --- a/src/components/ArchiveEditDialog.tsx +++ b/src/components/ArchiveEditDialog.tsx @@ -5,7 +5,7 @@ import { DialogHeader, DialogTitle } from '@/components/ui/dialog'; -import { Callout } from '@radix-ui/themes'; +import { Callout } from '@/components/ui/callout'; import { InfoCircledIcon } from '@radix-ui/react-icons'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; @@ -270,61 +270,62 @@ export const ArchiveEditDialog: React.FC = ({ return ( - +
{formatDate(day.startTime)} -
- {!isEditing ? ( - <> - - - - - ) : ( - <> - - - - )} -
+
-
+
+
+ {!isEditing ? ( + <> + + + + + ) : ( + <> + + + + )} +
{/* Day Summary */} {isEditing && ( - + @@ -334,7 +335,7 @@ export const ArchiveEditDialog: React.FC = ({ )} - + Summary of Day @@ -410,7 +411,7 @@ export const ArchiveEditDialog: React.FC = ({
) : ( -
+
Start Time: @@ -458,95 +459,99 @@ export const ArchiveEditDialog: React.FC = ({ Tasks ({tasks.length}) - - - - Task - Category - Project - Start Time - End Time - Duration - {isEditing && Actions} - - - - {tasks.map((task) => { - const category = categories.find( - (c) => c.id === task.category - ); - return ( - - -
-
{task.title}
- {task.description && ( -
- {task.description} -
- )} -
-
- - {category && ( -
-
- {category.name} +
+
+ + + Task + Category + Project/Client + Start Time + End Time + Duration + {isEditing && Actions} + + + + {tasks.map((task) => { + const category = categories.find( + (c) => c.id === task.category + ); + return ( + + +
+
{task.title}
+ + {task.description && ( +
+ {task.description} +
+ )} +
- )} -
- - {task.project && ( -
-
- {task.project} + + + {category && ( +
+
+ {category.name}
- {task.client && ( -
- {task.client} -
- )} -
- )} -
- - {formatTime12Hour(task.startTime)} - - - {task.endTime ? formatTime12Hour(task.endTime) : '-'} - - - {formatDuration(task.duration || 0)} - - {isEditing && ( + )} + -
- - -
+ {task.project && ( +
+
+ {task.project} +
+ {task.client && ( +
+ {task.client} +
+ )} +
+ )}
- )} - - ); - })} - -
+ + {formatTime12Hour(task.startTime)} + + + {task.endTime ? formatTime12Hour(task.endTime) : '-'} + + + {formatDuration(task.duration || 0)} + + {isEditing && ( + +
+ + +
+
+ )} + + ); + })} + + +
@@ -597,7 +602,7 @@ export const ArchiveEditDialog: React.FC = ({ /> )} -
+ ); }; diff --git a/src/components/ArchiveFilter.tsx b/src/components/ArchiveFilter.tsx index 2921dee..eecab45 100644 --- a/src/components/ArchiveFilter.tsx +++ b/src/components/ArchiveFilter.tsx @@ -13,6 +13,7 @@ import { import { X, ChevronDown, ChevronUp } from 'lucide-react'; import { Project } from '@/contexts/TimeTrackingContext'; import { TaskCategory } from '@/config/categories'; +import { ResetIcon } from '@radix-ui/react-icons'; export interface ArchiveFilterState { startDate: string; @@ -37,7 +38,7 @@ export const ArchiveFilter: React.FC = ({ projects, categories }) => { - const [isExpanded, setIsExpanded] = useState(true); + const [isExpanded, setIsExpanded] = useState(false); const handleReset = () => { onFilterChange({ @@ -53,7 +54,7 @@ export const ArchiveFilter: React.FC = ({ return ( - +
diff --git a/src/components/MobileNav.tsx b/src/components/MobileNav.tsx index 41d0a02..4edaacf 100644 --- a/src/components/MobileNav.tsx +++ b/src/components/MobileNav.tsx @@ -15,16 +15,16 @@ export const MobileNav = memo(function MobileNav() { icon: Home, label: 'Home' }, - { - path: '/archive', - icon: Archive, - label: 'Archive' - }, { path: '/projectlist', icon: FolderKanban, label: 'Projects' }, + { + path: '/archive', + icon: Archive, + label: 'Archive' + }, { path: '/settings', icon: Settings, @@ -44,11 +44,10 @@ export const MobileNav = memo(function MobileNav() { diff --git a/src/components/Navigation.tsx b/src/components/Navigation.tsx index e0e290a..56c2c5f 100644 --- a/src/components/Navigation.tsx +++ b/src/components/Navigation.tsx @@ -43,85 +43,85 @@ const SiteNavigationMenu = () => { return ( <> - - - -

- - Logo - TimeTracker - -

- {isDayStarted && tasks.length > 0 && ( - - - {formatDuration(runningTime)} - - )} -
-
- - + + + +

+ + Logo + TimeTracker + +

+ {isDayStarted && tasks.length > 0 && ( + + + {formatDuration(runningTime)} + + )}
- - - - - - `transition-all duration-200 flex items-center space-x-2 px-4 rounded-md h-10 bg-white border border-gray-200 hover:bg-accent hover:accent-foreground hover:border-input ... ${isActive ? 'bg-blue-200 hover:bg-accent hover:text-accent-foreground' : 'bg-white'}` - } - > - - Settings - - - -
- setShowAuthDialog(true)} /> -
-
-
-
+
+ + + + + + + + + `transition-all duration-200 flex items-center space-x-2 px-4 rounded-md h-10 bg-white border border-gray-200 hover:bg-accent hover:accent-foreground hover:border-input ... ${isActive ? 'bg-blue-200 hover:bg-accent hover:text-accent-foreground' : 'bg-white'}` + } + > + + Settings + + + +
+ setShowAuthDialog(true)} /> +
+
+
+ -
- -
-
+
+ +
+ - setShowAuthDialog(false)} - /> + setShowAuthDialog(false)} + /> - setShowExportDialog(false)} - /> + setShowExportDialog(false)} + /> - setShowProjectManagement(false)} - /> + setShowProjectManagement(false)} + /> ); }; diff --git a/src/components/SyncStatus.tsx b/src/components/SyncStatus.tsx index cf5e7f6..3175265 100644 --- a/src/components/SyncStatus.tsx +++ b/src/components/SyncStatus.tsx @@ -1,8 +1,12 @@ import { useState, useEffect, memo, useCallback } from 'react'; import { Cloud, CloudOff, RefreshCw, Save, AlertCircle } from 'lucide-react'; import { Button } from '@/components/ui/button'; -import { Popover, Tooltip } from "radix-ui"; -import { Cross2Icon } from "@radix-ui/react-icons"; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "@/components/ui/tooltip"; interface SyncStatusProps { isAuthenticated: boolean; @@ -36,106 +40,48 @@ export const SyncStatus = memo(function SyncStatus({ if (!isAuthenticated) { return (
- - - - - - - - Data saved to local storage only - - - - - + + + Data saved to local storage only + + +
); } return (
- {isSyncing ? ( - <> - - - ) : ( - <> - - - - - - -
- - Manual Sync Mode - - - Data saves only when you click "Save" or end the day - - - Last sync: {lastSyncTime ? new Date(lastSyncTime).toLocaleTimeString() : 'Never'} - - {hasUnsavedChanges && ( -
- - You have unsaved changes -
- )} - {onRefresh && ( - - )} -
- - - - -
-
-
- - )} +
); }); diff --git a/src/components/TaskEditDialog.tsx b/src/components/TaskEditDialog.tsx index 42413dd..3dc12b7 100644 --- a/src/components/TaskEditDialog.tsx +++ b/src/components/TaskEditDialog.tsx @@ -16,6 +16,7 @@ import { SelectTrigger, SelectValue } from '@/components/ui/select'; +import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Clock, Save } from 'lucide-react'; import { Task } from '@/contexts/TimeTrackingContext'; @@ -235,223 +236,233 @@ export const TaskEditDialog: React.FC = ({
- {/* Task Details */} - - - Task Details - - -
- - - setFormData((prev) => ({ ...prev, title: e.target.value })) - } - placeholder="Enter task title" - /> -
- -
- -