diff --git a/backend/Dockerfile b/backend/Dockerfile index 6dfcf45..833ecd2 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -53,7 +53,7 @@ COPY --from=builder /app/src/core /app/migrations/core # Copy entrypoint script for permission checks COPY scripts/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh -RUN chmod +x /usr/local/bin/docker-entrypoint.sh +RUN chmod 755 /usr/local/bin/docker-entrypoint.sh # Change ownership to non-root user RUN chown -R nodejs:nodejs /app diff --git a/frontend/index.html b/frontend/index.html index 9834c22..8cad153 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -4,6 +4,7 @@ +
@@ -988,7 +988,7 @@ export const AdminBackupMobileScreen: React.FC = () => { {/* Delete Backup Confirmation Modal */} {showDeleteBackupConfirm && (
Are you sure you want to delete "{selectedBackup?.filename}"? This action cannot be @@ -1016,7 +1016,7 @@ export const AdminBackupMobileScreen: React.FC = () => { {/* Delete Schedule Confirmation Modal */} {showDeleteScheduleConfirm && (
Are you sure you want to delete "{selectedSchedule?.name}"? This action cannot be diff --git a/frontend/src/features/admin/mobile/AdminCatalogMobileScreen.tsx b/frontend/src/features/admin/mobile/AdminCatalogMobileScreen.tsx index 1ec3f2e..4167f92 100644 --- a/frontend/src/features/admin/mobile/AdminCatalogMobileScreen.tsx +++ b/frontend/src/features/admin/mobile/AdminCatalogMobileScreen.tsx @@ -379,14 +379,14 @@ export const AdminCatalogMobileScreen: React.FC = () => { {menuOpen && (
+
Are you sure you want to delete{' '} {deleteSheet.item.year} {deleteSheet.item.make} {deleteSheet.item.model}{' '} @@ -441,7 +441,7 @@ export const AdminCatalogMobileScreen: React.FC = () => { setDeleteSheet({ open: false, item: null })} disabled={deleting} - className="flex-1 bg-slate-200 text-slate-700 py-3 rounded-lg font-medium hover:bg-slate-300 transition disabled:opacity-50" + className="flex-1 bg-slate-200 dark:bg-gray-700 text-slate-700 dark:text-gray-200 py-3 rounded-lg font-medium hover:bg-slate-300 dark:hover:bg-gray-600 transition disabled:opacity-50" style={{ minHeight: '44px' }} > Cancel @@ -466,7 +466,7 @@ export const AdminCatalogMobileScreen: React.FC = () => { {/* Import Preview/Results Sheet */} {importSheet && (importPreview || importResult) && ( - + {importResult ? 'Import Results' : 'Import Preview'} diff --git a/frontend/src/features/admin/mobile/AdminEmailTemplatesMobileScreen.tsx b/frontend/src/features/admin/mobile/AdminEmailTemplatesMobileScreen.tsx index 5448266..94c9ba0 100644 --- a/frontend/src/features/admin/mobile/AdminEmailTemplatesMobileScreen.tsx +++ b/frontend/src/features/admin/mobile/AdminEmailTemplatesMobileScreen.tsx @@ -238,7 +238,7 @@ export const AdminEmailTemplatesMobileScreen: React.FC = () => { {editingTemplate.variables.map((variable) => ( {`{{${variable}}}`} @@ -250,7 +250,7 @@ export const AdminEmailTemplatesMobileScreen: React.FC = () => { Cancel diff --git a/frontend/src/features/admin/mobile/AdminUsersMobileScreen.tsx b/frontend/src/features/admin/mobile/AdminUsersMobileScreen.tsx index 1a65a88..4701fbf 100644 --- a/frontend/src/features/admin/mobile/AdminUsersMobileScreen.tsx +++ b/frontend/src/features/admin/mobile/AdminUsersMobileScreen.tsx @@ -37,8 +37,8 @@ const Modal: React.FC = ({ isOpen, onClose, title, children, actions return ( - - {title} + + {title} {children} {actions || ( @@ -337,7 +337,7 @@ export const AdminUsersMobileScreen: React.FC = () => { value={searchInput} onChange={(e) => setSearchInput(e.target.value)} onKeyPress={(e) => e.key === 'Enter' && handleSearch()} - className="w-full px-4 py-3 rounded-lg border border-slate-200 focus:outline-none focus:ring-2 focus:ring-blue-500 min-h-[44px]" + className="w-full px-4 py-3 rounded-lg border border-slate-200 dark:border-silverstone dark:bg-scuro dark:text-avus focus:outline-none focus:ring-2 focus:ring-blue-500 min-h-[44px]" /> {searchInput && ( { handleTierFilterChange(e.target.value as SubscriptionTier | '')} - className="w-full px-3 py-2 rounded-lg border border-slate-200 min-h-[44px]" + className="w-full px-3 py-2 rounded-lg border border-slate-200 dark:border-silverstone dark:bg-scuro dark:text-avus min-h-[44px]" > All Tiers Free @@ -393,7 +393,7 @@ export const AdminUsersMobileScreen: React.FC = () => { handleStatusFilterChange(e.target.value as 'active' | 'deactivated' | 'all')} - className="w-full px-3 py-2 rounded-lg border border-slate-200 min-h-[44px]" + className="w-full px-3 py-2 rounded-lg border border-slate-200 dark:border-silverstone dark:bg-scuro dark:text-avus min-h-[44px]" > All Active diff --git a/frontend/src/features/auth/pages/VerifyEmailPage.tsx b/frontend/src/features/auth/pages/VerifyEmailPage.tsx index a24b751..42f13e9 100644 --- a/frontend/src/features/auth/pages/VerifyEmailPage.tsx +++ b/frontend/src/features/auth/pages/VerifyEmailPage.tsx @@ -114,7 +114,7 @@ export const VerifyEmailPage: React.FC = () => { return ( - + { /> - Check Your Email - + Check Your Email + We've sent a verification link to {email && ( @@ -143,7 +143,7 @@ export const VerifyEmailPage: React.FC = () => { - + Click the link in the email to verify your account. Once verified, you can log in to complete your profile setup. diff --git a/frontend/src/features/documents/mobile/DocumentsMobileScreen.tsx b/frontend/src/features/documents/mobile/DocumentsMobileScreen.tsx index e9133a0..da0aaa7 100644 --- a/frontend/src/features/documents/mobile/DocumentsMobileScreen.tsx +++ b/frontend/src/features/documents/mobile/DocumentsMobileScreen.tsx @@ -56,8 +56,8 @@ export const DocumentsMobileScreen: React.FC = () => { - Documents - Loading... + Documents + Loading... @@ -77,8 +77,8 @@ export const DocumentsMobileScreen: React.FC = () => { - Login Required - Please log in to view your documents + Login Required + Please log in to view your documents loginWithRedirect()} className="w-full px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors" @@ -106,8 +106,8 @@ export const DocumentsMobileScreen: React.FC = () => { - Session Expired - Your session has expired. Please log in again. + Session Expired + Your session has expired. Please log in again. loginWithRedirect()} className="w-full px-4 py-2 bg-orange-600 text-white rounded-lg hover:bg-orange-700 transition-colors" @@ -126,13 +126,13 @@ export const DocumentsMobileScreen: React.FC = () => { setIsAddOpen(false)} /> - Documents + Documents setIsAddOpen(true)} className="min-h-[44px]">Add Document - {isLoading && Loading...} + {isLoading && Loading...} {hasError && !isAuthError && ( @@ -162,8 +162,8 @@ export const DocumentsMobileScreen: React.FC = () => { - No documents yet - Documents will appear here once you create them + No documents yet + Documents will appear here once you create them )} @@ -174,8 +174,8 @@ export const DocumentsMobileScreen: React.FC = () => { return ( - {doc.title} - {doc.documentType} • {vehicleLabel} + {doc.title} + {doc.documentType} • {vehicleLabel} navigate(`/garage/documents/${doc.id}`)}>Open diff --git a/frontend/src/features/fuel-logs/components/FuelLogForm.tsx b/frontend/src/features/fuel-logs/components/FuelLogForm.tsx index 0c58daf..f379a2b 100644 --- a/frontend/src/features/fuel-logs/components/FuelLogForm.tsx +++ b/frontend/src/features/fuel-logs/components/FuelLogForm.tsx @@ -188,10 +188,16 @@ const FuelLogFormComponent: React.FC<{ onSuccess?: () => void; initial?: Partial InputProps={{ readOnly: true, sx: (theme) => ({ - backgroundColor: theme.palette.mode === 'dark' ? '#4C4E4D' : 'grey.50', + backgroundColor: 'grey.50', + ...theme.applyStyles('dark', { + backgroundColor: '#4C4E4D', + }), '& .MuiOutlinedInput-input': { cursor: 'default', - color: theme.palette.mode === 'dark' ? '#F2F3F6' : 'inherit', + color: 'inherit', + ...theme.applyStyles('dark', { + color: '#F2F3F6', + }), }, }), }} diff --git a/frontend/src/features/fuel-logs/components/StationPicker.tsx b/frontend/src/features/fuel-logs/components/StationPicker.tsx index a29eee0..eb9bd97 100644 --- a/frontend/src/features/fuel-logs/components/StationPicker.tsx +++ b/frontend/src/features/fuel-logs/components/StationPicker.tsx @@ -333,7 +333,10 @@ export const StationPicker: React.FC = ({ sx={(theme) => ({ '& .MuiAutocomplete-groupLabel': { fontWeight: 600, - backgroundColor: theme.palette.mode === 'dark' ? '#4C4E4D' : 'grey.100', + backgroundColor: 'grey.100', + ...theme.applyStyles('dark', { + backgroundColor: '#4C4E4D', + }), fontSize: '0.75rem', textTransform: 'uppercase', letterSpacing: '0.5px' diff --git a/frontend/src/features/settings/mobile/DeleteAccountModal.tsx b/frontend/src/features/settings/mobile/DeleteAccountModal.tsx index b67c39d..d078628 100644 --- a/frontend/src/features/settings/mobile/DeleteAccountModal.tsx +++ b/frontend/src/features/settings/mobile/DeleteAccountModal.tsx @@ -36,13 +36,13 @@ export const DeleteAccountModal: React.FC = ({ isOpen, return ( - - Delete Account + + Delete Account {/* Warning Alert */} - - 30-Day Grace Period - + + 30-Day Grace Period + Your account will be scheduled for deletion in 30 days. You can cancel this request at any time during the grace period by logging back in. @@ -50,7 +50,7 @@ export const DeleteAccountModal: React.FC = ({ isOpen, {/* Confirmation Input */} - + Type DELETE to confirm = ({ isOpen, value={confirmationText} onChange={(e) => setConfirmationText(e.target.value)} placeholder="DELETE" - className={`w-full px-3 py-2 border rounded-lg focus:ring-2 ${ + className={`w-full px-3 py-2 border rounded-lg focus:ring-2 dark:bg-scuro dark:text-avus ${ confirmationText.length > 0 && confirmationText !== 'DELETE' - ? 'border-red-300 focus:ring-red-500 focus:border-red-500' - : 'border-slate-300 focus:ring-red-500 focus:border-red-500' + ? 'border-red-300 dark:border-red-700 focus:ring-red-500 focus:border-red-500' + : 'border-slate-300 dark:border-silverstone focus:ring-red-500 focus:border-red-500' }`} style={{ fontSize: '16px', minHeight: '44px' }} /> - Type the word "DELETE" (all caps) to confirm + Type the word "DELETE" (all caps) to confirm {/* Action Buttons */} @@ -73,7 +73,7 @@ export const DeleteAccountModal: React.FC = ({ isOpen, Cancel diff --git a/frontend/src/features/settings/mobile/MobileSettingsScreen.tsx b/frontend/src/features/settings/mobile/MobileSettingsScreen.tsx index c9e81af..52d3467 100644 --- a/frontend/src/features/settings/mobile/MobileSettingsScreen.tsx +++ b/frontend/src/features/settings/mobile/MobileSettingsScreen.tsx @@ -25,9 +25,9 @@ const ToggleSwitch: React.FC = ({ }) => ( - {label} + {label} {description && ( - {description} + {description} )} = ({ isOpen, onClose, title, children }) => { if (!isOpen) return null; return ( - - - {title} + + + {title} {children} Close @@ -184,8 +184,8 @@ export const MobileSettingsScreen: React.FC = () => { {/* Header */} - Settings - Manage your account and preferences + Settings + Manage your account and preferences {/* Pending Deletion Banner */} @@ -195,7 +195,7 @@ export const MobileSettingsScreen: React.FC = () => { - Profile + Profile {!isEditingProfile && !profileLoading && ( { ) : isEditingProfile ? ( - + Email - Email is managed by your account provider + Email is managed by your account provider - + Display Name { value={editedDisplayName} onChange={(e) => setEditedDisplayName(e.target.value)} placeholder="Enter your display name" - className="w-full px-3 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500 dark:bg-nero dark:border-silverstone dark:text-avus" + className="w-full px-3 py-2 border border-slate-300 dark:border-silverstone rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500 dark:bg-nero dark:text-avus" style={{ fontSize: '16px', minHeight: '44px' }} /> - + Notification Email { value={editedNotificationEmail} onChange={(e) => setEditedNotificationEmail(e.target.value)} placeholder="Leave blank to use your primary email" - className="w-full px-3 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500 dark:bg-nero dark:border-silverstone dark:text-avus" + className="w-full px-3 py-2 border border-slate-300 dark:border-silverstone rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500 dark:bg-nero dark:text-avus" style={{ fontSize: '16px', minHeight: '44px' }} /> - Optional: Use a different email for notifications + Optional: Use a different email for notifications Cancel @@ -294,21 +294,21 @@ export const MobileSettingsScreen: React.FC = () => { )} - + {profile?.displayName || user?.name || 'User'} - {profile?.email || user?.email} + {profile?.email || user?.email} - + - Display Name - {profile?.displayName || 'Not set'} + Display Name + {profile?.displayName || 'Not set'} - Notification Email - {profile?.notificationEmail || 'Using primary email'} + Notification Email + {profile?.notificationEmail || 'Using primary email'} @@ -319,7 +319,7 @@ export const MobileSettingsScreen: React.FC = () => { {/* Notifications Section */} - Notifications + Notifications { {/* Appearance & Units Section */} - Appearance & Units + Appearance & Units { - Unit System - + Unit System + Currently using {settings.unitSystem === 'imperial' ? 'Miles, Gallons, MPG, USD' : 'Km, Liters, L/100km, EUR'} @@ -385,7 +385,7 @@ export const MobileSettingsScreen: React.FC = () => { {/* Data Management Section */} - Data Management + Data Management setShowDataExport(true)} @@ -393,7 +393,7 @@ export const MobileSettingsScreen: React.FC = () => { > Export My Data - + Download a copy of all your vehicle and fuel data @@ -421,7 +421,7 @@ export const MobileSettingsScreen: React.FC = () => { {!adminLoading && isAdmin && ( - Admin Console + Admin Console navigateToScreen('AdminUsers')} @@ -463,11 +463,11 @@ export const MobileSettingsScreen: React.FC = () => { {/* Account Actions Section */} - Account Actions + Account Actions Sign Out @@ -487,7 +487,7 @@ export const MobileSettingsScreen: React.FC = () => { onClose={() => setShowDataExport(false)} title="Export Data" > - + This will create a downloadable file containing all your vehicle data, fuel logs, and preferences. diff --git a/frontend/src/index.css b/frontend/src/index.css index 2023212..f46efae 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -13,4 +13,22 @@ body { * { box-sizing: border-box; +} + +:root { + color-scheme: light; +} + +:root.dark { + color-scheme: dark; +} + +html { + background-color: #ffffff; + color: #1e293b; +} + +html.dark { + background-color: #231F1C; + color: #F2F3F6; } \ No newline at end of file diff --git a/frontend/src/shared-minimal/components/mobile/GlassCard.tsx b/frontend/src/shared-minimal/components/mobile/GlassCard.tsx index 6413641..54a7348 100644 --- a/frontend/src/shared-minimal/components/mobile/GlassCard.tsx +++ b/frontend/src/shared-minimal/components/mobile/GlassCard.tsx @@ -28,7 +28,7 @@ export const GlassCard: React.FC = ({ return ( = ({ }) => { return ( - + {children} diff --git a/frontend/src/shared-minimal/components/mobile/MobilePill.tsx b/frontend/src/shared-minimal/components/mobile/MobilePill.tsx index 61d3848..b121275 100644 --- a/frontend/src/shared-minimal/components/mobile/MobilePill.tsx +++ b/frontend/src/shared-minimal/components/mobile/MobilePill.tsx @@ -29,7 +29,7 @@ export const MobilePill: React.FC = ({ "group h-11 rounded-2xl text-sm font-medium border transition flex items-center justify-center gap-2 backdrop-blur", active ? "text-white border-transparent shadow-lg bg-gradient-moto" - : "bg-white/80 text-slate-800 border-slate-200 hover:bg-slate-50", + : "bg-white/80 dark:bg-nero/80 text-slate-800 dark:text-avus border-slate-200 dark:border-slate-700 hover:bg-slate-50 dark:hover:bg-inactive", className )} >
We've sent a verification link to
Click the link in the email to verify your account.
Once verified, you can log in to complete your profile setup.
Please log in to view your documents
Your session has expired. Please log in again.
No documents yet
Documents will appear here once you create them
30-Day Grace Period
Your account will be scheduled for deletion in 30 days. You can cancel this request at any time during the grace period by logging back in.
Type the word "DELETE" (all caps) to confirm
{label}
{description}
Manage your account and preferences
Email is managed by your account provider
Optional: Use a different email for notifications
{profile?.displayName || user?.name || 'User'}
{profile?.email || user?.email}
Display Name
{profile?.displayName || 'Not set'}
Notification Email
{profile?.notificationEmail || 'Using primary email'}
Unit System
Currently using {settings.unitSystem === 'imperial' ? 'Miles, Gallons, MPG, USD' : 'Km, Liters, L/100km, EUR'}
Download a copy of all your vehicle and fuel data
This will create a downloadable file containing all your vehicle data, fuel logs, and preferences.