fix: post Dark mode fixes

This commit is contained in:
Eric Gullickson
2025-12-27 20:00:51 -06:00
parent 1799f2fee1
commit 69171f7778
17 changed files with 125 additions and 95 deletions

View File

@@ -53,7 +53,7 @@ COPY --from=builder /app/src/core /app/migrations/core
# Copy entrypoint script for permission checks # Copy entrypoint script for permission checks
COPY scripts/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh 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 # Change ownership to non-root user
RUN chown -R nodejs:nodejs /app RUN chown -R nodejs:nodejs /app

View File

@@ -4,6 +4,7 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> <link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="color-scheme" content="light dark">
<title>MotoVaultPro</title> <title>MotoVaultPro</title>
<!-- Runtime config MUST load synchronously before any module scripts --> <!-- Runtime config MUST load synchronously before any module scripts -->
<script src="/config.js"></script> <script src="/config.js"></script>

View File

@@ -5,7 +5,7 @@
import React from 'react'; import React from 'react';
import { useAuth0 } from '@auth0/auth0-react'; import { useAuth0 } from '@auth0/auth0-react';
import { Link, useLocation } from 'react-router-dom'; import { Link, useLocation } from 'react-router-dom';
import { Container, Paper, Typography, Box, IconButton, Avatar, useTheme } from '@mui/material'; import { Container, Paper, Typography, Box, IconButton, Avatar } from '@mui/material';
import DirectionsCarRoundedIcon from '@mui/icons-material/DirectionsCarRounded'; import DirectionsCarRoundedIcon from '@mui/icons-material/DirectionsCarRounded';
import LocalGasStationRoundedIcon from '@mui/icons-material/LocalGasStationRounded'; import LocalGasStationRoundedIcon from '@mui/icons-material/LocalGasStationRounded';
import BuildRoundedIcon from '@mui/icons-material/BuildRounded'; import BuildRoundedIcon from '@mui/icons-material/BuildRounded';
@@ -28,7 +28,6 @@ export const Layout: React.FC<LayoutProps> = ({ children, mobileMode = false })
const { user, logout } = useAuth0(); const { user, logout } = useAuth0();
const { sidebarOpen, toggleSidebar, setSidebarOpen } = useAppStore(); const { sidebarOpen, toggleSidebar, setSidebarOpen } = useAppStore();
const location = useLocation(); const location = useLocation();
const theme = useTheme();
// Sync theme preference with backend // Sync theme preference with backend
useThemeSync(); useThemeSync();
@@ -128,14 +127,17 @@ export const Layout: React.FC<LayoutProps> = ({ children, mobileMode = false })
}} }}
> >
<Box <Box
sx={{ sx={(theme) => ({
backgroundColor: theme.palette.mode === 'light' ? 'primary.main' : 'transparent', backgroundColor: 'primary.main',
...theme.applyStyles('dark', {
backgroundColor: 'transparent',
}),
borderRadius: 1, borderRadius: 1,
px: 1, px: 1,
py: 0.5, py: 0.5,
display: 'inline-flex', display: 'inline-flex',
alignItems: 'center' alignItems: 'center'
}} })}
> >
<img <img
src="/images/logos/motovaultpro-title-slogan.png" src="/images/logos/motovaultpro-title-slogan.png"

View File

@@ -610,7 +610,7 @@ export const AdminBackupMobileScreen: React.FC = () => {
{showRestoreConfirm && ( {showRestoreConfirm && (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4"> <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4">
<div className="bg-white rounded-lg p-6 max-w-sm w-full"> <div className="bg-white dark:bg-scuro rounded-lg p-6 max-w-sm w-full">
<h3 className="text-lg font-semibold text-slate-800 mb-4">Confirm Restore</h3> <h3 className="text-lg font-semibold text-slate-800 mb-4">Confirm Restore</h3>
<div className="bg-red-50 border border-red-200 rounded-lg p-3 mb-4"> <div className="bg-red-50 border border-red-200 rounded-lg p-3 mb-4">
<p className="text-xs text-red-800"> <p className="text-xs text-red-800">
@@ -988,7 +988,7 @@ export const AdminBackupMobileScreen: React.FC = () => {
{/* Delete Backup Confirmation Modal */} {/* Delete Backup Confirmation Modal */}
{showDeleteBackupConfirm && ( {showDeleteBackupConfirm && (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4"> <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4">
<div className="bg-white rounded-lg p-6 max-w-sm w-full"> <div className="bg-white dark:bg-scuro rounded-lg p-6 max-w-sm w-full">
<h3 className="text-lg font-semibold text-slate-800 mb-4">Delete Backup</h3> <h3 className="text-lg font-semibold text-slate-800 mb-4">Delete Backup</h3>
<p className="text-sm text-slate-600 mb-4"> <p className="text-sm text-slate-600 mb-4">
Are you sure you want to delete "{selectedBackup?.filename}"? This action cannot be 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 */} {/* Delete Schedule Confirmation Modal */}
{showDeleteScheduleConfirm && ( {showDeleteScheduleConfirm && (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4"> <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4">
<div className="bg-white rounded-lg p-6 max-w-sm w-full"> <div className="bg-white dark:bg-scuro rounded-lg p-6 max-w-sm w-full">
<h3 className="text-lg font-semibold text-slate-800 mb-4">Delete Schedule</h3> <h3 className="text-lg font-semibold text-slate-800 mb-4">Delete Schedule</h3>
<p className="text-sm text-slate-600 mb-4"> <p className="text-sm text-slate-600 mb-4">
Are you sure you want to delete "{selectedSchedule?.name}"? This action cannot be Are you sure you want to delete "{selectedSchedule?.name}"? This action cannot be

View File

@@ -379,14 +379,14 @@ export const AdminCatalogMobileScreen: React.FC = () => {
{menuOpen && ( {menuOpen && (
<div className="fixed inset-0 bg-black bg-opacity-50 z-50 flex items-end justify-center"> <div className="fixed inset-0 bg-black bg-opacity-50 z-50 flex items-end justify-center">
<div <div
className="bg-white rounded-t-2xl w-full max-w-lg p-4 space-y-2 animate-slide-up" className="bg-white dark:bg-scuro rounded-t-2xl w-full max-w-lg p-4 space-y-2 animate-slide-up"
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
> >
<div className="flex items-center justify-between mb-2"> <div className="flex items-center justify-between mb-2">
<h2 className="text-lg font-semibold text-slate-800">Options</h2> <h2 className="text-lg font-semibold text-slate-800 dark:text-avus">Options</h2>
<button <button
onClick={() => setMenuOpen(false)} onClick={() => setMenuOpen(false)}
className="p-2 text-slate-500 hover:text-slate-700" className="p-2 text-slate-500 dark:text-titanio hover:text-slate-700 dark:hover:text-avus"
style={{ minHeight: '44px', minWidth: '44px' }} style={{ minHeight: '44px', minWidth: '44px' }}
> >
<Close /> <Close />
@@ -396,7 +396,7 @@ export const AdminCatalogMobileScreen: React.FC = () => {
<button <button
onClick={handleImportClick} onClick={handleImportClick}
disabled={importPreviewMutation.isPending} disabled={importPreviewMutation.isPending}
className="w-full flex items-center gap-3 px-4 py-3 text-left text-slate-700 hover:bg-slate-50 rounded-lg transition" className="w-full flex items-center gap-3 px-4 py-3 text-left text-slate-700 dark:text-avus hover:bg-slate-50 dark:hover:bg-gray-800 rounded-lg transition"
style={{ minHeight: '44px' }} style={{ minHeight: '44px' }}
> >
<FileUpload /> <FileUpload />
@@ -406,7 +406,7 @@ export const AdminCatalogMobileScreen: React.FC = () => {
<button <button
onClick={handleExport} onClick={handleExport}
disabled={exportMutation.isPending} disabled={exportMutation.isPending}
className="w-full flex items-center gap-3 px-4 py-3 text-left text-slate-700 hover:bg-slate-50 rounded-lg transition" className="w-full flex items-center gap-3 px-4 py-3 text-left text-slate-700 dark:text-avus hover:bg-slate-50 dark:hover:bg-gray-800 rounded-lg transition"
style={{ minHeight: '44px' }} style={{ minHeight: '44px' }}
> >
<FileDownload /> <FileDownload />
@@ -415,7 +415,7 @@ export const AdminCatalogMobileScreen: React.FC = () => {
<button <button
onClick={() => setMenuOpen(false)} onClick={() => setMenuOpen(false)}
className="w-full bg-slate-100 text-slate-700 py-3 rounded-lg font-medium hover:bg-slate-200 transition mt-4" className="w-full bg-slate-100 dark:bg-gray-700 text-slate-700 dark:text-gray-200 py-3 rounded-lg font-medium hover:bg-slate-200 dark:hover:bg-gray-600 transition mt-4"
style={{ minHeight: '44px' }} style={{ minHeight: '44px' }}
> >
Cancel Cancel
@@ -427,9 +427,9 @@ export const AdminCatalogMobileScreen: React.FC = () => {
{/* Delete Confirmation Sheet */} {/* Delete Confirmation Sheet */}
{deleteSheet.open && deleteSheet.item && ( {deleteSheet.open && deleteSheet.item && (
<div className="fixed inset-0 bg-black bg-opacity-50 z-50 flex items-end justify-center"> <div className="fixed inset-0 bg-black bg-opacity-50 z-50 flex items-end justify-center">
<div className="bg-white rounded-t-2xl w-full max-w-lg p-6 space-y-4 animate-slide-up"> <div className="bg-white dark:bg-scuro rounded-t-2xl w-full max-w-lg p-6 space-y-4 animate-slide-up">
<h2 className="text-xl font-bold text-slate-800">Delete Configuration?</h2> <h2 className="text-xl font-bold text-slate-800 dark:text-avus">Delete Configuration?</h2>
<p className="text-slate-600"> <p className="text-slate-600 dark:text-titanio">
Are you sure you want to delete{' '} Are you sure you want to delete{' '}
<strong> <strong>
{deleteSheet.item.year} {deleteSheet.item.make} {deleteSheet.item.model}{' '} {deleteSheet.item.year} {deleteSheet.item.make} {deleteSheet.item.model}{' '}
@@ -441,7 +441,7 @@ export const AdminCatalogMobileScreen: React.FC = () => {
<button <button
onClick={() => setDeleteSheet({ open: false, item: null })} onClick={() => setDeleteSheet({ open: false, item: null })}
disabled={deleting} 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' }} style={{ minHeight: '44px' }}
> >
Cancel Cancel
@@ -466,7 +466,7 @@ export const AdminCatalogMobileScreen: React.FC = () => {
{/* Import Preview/Results Sheet */} {/* Import Preview/Results Sheet */}
{importSheet && (importPreview || importResult) && ( {importSheet && (importPreview || importResult) && (
<div className="fixed inset-0 bg-black bg-opacity-50 z-50 flex items-end justify-center"> <div className="fixed inset-0 bg-black bg-opacity-50 z-50 flex items-end justify-center">
<div className="bg-white rounded-t-2xl w-full max-w-lg p-6 space-y-4 animate-slide-up max-h-[80vh] overflow-y-auto"> <div className="bg-white dark:bg-scuro rounded-t-2xl w-full max-w-lg p-6 space-y-4 animate-slide-up max-h-[80vh] overflow-y-auto">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<h2 className="text-xl font-bold text-slate-800"> <h2 className="text-xl font-bold text-slate-800">
{importResult ? 'Import Results' : 'Import Preview'} {importResult ? 'Import Results' : 'Import Preview'}

View File

@@ -238,7 +238,7 @@ export const AdminEmailTemplatesMobileScreen: React.FC = () => {
{editingTemplate.variables.map((variable) => ( {editingTemplate.variables.map((variable) => (
<span <span
key={variable} key={variable}
className="inline-block px-2 py-1 bg-white border border-blue-300 rounded text-xs font-mono text-blue-700" className="inline-block px-2 py-1 bg-white dark:bg-gray-800 border border-blue-300 dark:border-blue-600 rounded text-xs font-mono text-blue-700 dark:text-blue-400"
> >
{`{{${variable}}}`} {`{{${variable}}}`}
</span> </span>
@@ -250,7 +250,7 @@ export const AdminEmailTemplatesMobileScreen: React.FC = () => {
<div className="flex gap-2 pt-2"> <div className="flex gap-2 pt-2">
<button <button
onClick={handleCloseEdit} onClick={handleCloseEdit}
className="flex-1 px-4 py-3 bg-gray-100 text-gray-700 rounded-lg font-medium hover:bg-gray-200 transition-colors min-h-[44px]" className="flex-1 px-4 py-3 bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-200 rounded-lg font-medium hover:bg-gray-200 dark:hover:bg-gray-600 transition-colors min-h-[44px]"
> >
Cancel Cancel
</button> </button>

View File

@@ -37,8 +37,8 @@ const Modal: React.FC<ModalProps> = ({ isOpen, onClose, title, children, actions
return ( return (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4"> <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4">
<div className="bg-white rounded-xl p-6 max-w-sm w-full shadow-xl"> <div className="bg-white dark:bg-scuro rounded-xl p-6 max-w-sm w-full shadow-xl">
<h3 className="text-lg font-semibold text-slate-800 mb-4">{title}</h3> <h3 className="text-lg font-semibold text-slate-800 dark:text-avus mb-4">{title}</h3>
{children} {children}
<div className="flex justify-end gap-2 mt-4"> <div className="flex justify-end gap-2 mt-4">
{actions || ( {actions || (
@@ -337,7 +337,7 @@ export const AdminUsersMobileScreen: React.FC = () => {
value={searchInput} value={searchInput}
onChange={(e) => setSearchInput(e.target.value)} onChange={(e) => setSearchInput(e.target.value)}
onKeyPress={(e) => e.key === 'Enter' && handleSearch()} 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 && ( {searchInput && (
<button <button
@@ -378,7 +378,7 @@ export const AdminUsersMobileScreen: React.FC = () => {
<select <select
value={params.tier || ''} value={params.tier || ''}
onChange={(e) => handleTierFilterChange(e.target.value as SubscriptionTier | '')} onChange={(e) => 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]"
> >
<option value="">All Tiers</option> <option value="">All Tiers</option>
<option value="free">Free</option> <option value="free">Free</option>
@@ -393,7 +393,7 @@ export const AdminUsersMobileScreen: React.FC = () => {
<select <select
value={params.status || 'all'} value={params.status || 'all'}
onChange={(e) => handleStatusFilterChange(e.target.value as 'active' | 'deactivated' | 'all')} onChange={(e) => 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]"
> >
<option value="all">All</option> <option value="all">All</option>
<option value="active">Active</option> <option value="active">Active</option>

View File

@@ -114,7 +114,7 @@ export const VerifyEmailPage: React.FC = () => {
return ( return (
<div className="min-h-screen bg-gradient-to-br from-slate-50 via-white to-rose-50 dark:from-paper dark:via-nero dark:to-paper flex items-center justify-center p-4"> <div className="min-h-screen bg-gradient-to-br from-slate-50 via-white to-rose-50 dark:from-paper dark:via-nero dark:to-paper flex items-center justify-center p-4">
<div className="w-full max-w-md"> <div className="w-full max-w-md">
<div className="bg-white rounded-lg shadow-lg p-8"> <div className="bg-white dark:bg-scuro rounded-lg shadow-lg p-8">
<div className="text-center mb-8"> <div className="text-center mb-8">
<div className="mx-auto w-16 h-16 bg-primary-100 rounded-full flex items-center justify-center mb-4"> <div className="mx-auto w-16 h-16 bg-primary-100 rounded-full flex items-center justify-center mb-4">
<svg <svg
@@ -131,8 +131,8 @@ export const VerifyEmailPage: React.FC = () => {
/> />
</svg> </svg>
</div> </div>
<h1 className="text-2xl font-bold text-gray-800 mb-2">Check Your Email</h1> <h1 className="text-2xl font-bold text-gray-800 dark:text-avus mb-2">Check Your Email</h1>
<p className="text-gray-600"> <p className="text-gray-600 dark:text-titanio">
We've sent a verification link to We've sent a verification link to
</p> </p>
{email && ( {email && (
@@ -143,7 +143,7 @@ export const VerifyEmailPage: React.FC = () => {
</div> </div>
<div className="space-y-4"> <div className="space-y-4">
<div className="bg-slate-50 rounded-lg p-4 text-sm text-gray-700"> <div className="bg-slate-50 dark:bg-gray-800 rounded-lg p-4 text-sm text-gray-700 dark:text-gray-300">
<p className="mb-2">Click the link in the email to verify your account.</p> <p className="mb-2">Click the link in the email to verify your account.</p>
<p>Once verified, you can log in to complete your profile setup.</p> <p>Once verified, you can log in to complete your profile setup.</p>
</div> </div>

View File

@@ -56,8 +56,8 @@ export const DocumentsMobileScreen: React.FC = () => {
<div className="space-y-4"> <div className="space-y-4">
<GlassCard> <GlassCard>
<div className="p-4"> <div className="p-4">
<h2 className="text-lg font-semibold text-slate-800 mb-2">Documents</h2> <h2 className="text-lg font-semibold text-slate-800 dark:text-avus mb-2">Documents</h2>
<div className="text-slate-500 py-6 text-center">Loading...</div> <div className="text-slate-500 dark:text-titanio py-6 text-center">Loading...</div>
</div> </div>
</GlassCard> </GlassCard>
</div> </div>
@@ -77,8 +77,8 @@ export const DocumentsMobileScreen: React.FC = () => {
</svg> </svg>
</div> </div>
</div> </div>
<h3 className="text-lg font-semibold text-slate-800 mb-2">Login Required</h3> <h3 className="text-lg font-semibold text-slate-800 dark:text-avus mb-2">Login Required</h3>
<p className="text-slate-600 text-sm mb-4">Please log in to view your documents</p> <p className="text-slate-600 dark:text-titanio text-sm mb-4">Please log in to view your documents</p>
<button <button
onClick={() => loginWithRedirect()} onClick={() => loginWithRedirect()}
className="w-full px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors" 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 = () => {
</svg> </svg>
</div> </div>
</div> </div>
<h3 className="text-lg font-semibold text-slate-800 mb-2">Session Expired</h3> <h3 className="text-lg font-semibold text-slate-800 dark:text-avus mb-2">Session Expired</h3>
<p className="text-slate-600 text-sm mb-4">Your session has expired. Please log in again.</p> <p className="text-slate-600 dark:text-titanio text-sm mb-4">Your session has expired. Please log in again.</p>
<button <button
onClick={() => loginWithRedirect()} onClick={() => loginWithRedirect()}
className="w-full px-4 py-2 bg-orange-600 text-white rounded-lg hover:bg-orange-700 transition-colors" 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 = () => {
<AddDocumentDialog open={isAddOpen} onClose={() => setIsAddOpen(false)} /> <AddDocumentDialog open={isAddOpen} onClose={() => setIsAddOpen(false)} />
<GlassCard> <GlassCard>
<div className="p-4"> <div className="p-4">
<h2 className="text-lg font-semibold text-slate-800 mb-2">Documents</h2> <h2 className="text-lg font-semibold text-slate-800 dark:text-avus mb-2">Documents</h2>
<div className="flex justify-end mb-2"> <div className="flex justify-end mb-2">
<Button onClick={() => setIsAddOpen(true)} className="min-h-[44px]">Add Document</Button> <Button onClick={() => setIsAddOpen(true)} className="min-h-[44px]">Add Document</Button>
</div> </div>
{isLoading && <div className="text-slate-500 py-6 text-center">Loading...</div>} {isLoading && <div className="text-slate-500 dark:text-titanio py-6 text-center">Loading...</div>}
{hasError && !isAuthError && ( {hasError && !isAuthError && (
<div className="py-6 text-center"> <div className="py-6 text-center">
@@ -162,8 +162,8 @@ export const DocumentsMobileScreen: React.FC = () => {
</svg> </svg>
</div> </div>
</div> </div>
<p className="text-slate-600 text-sm mb-3">No documents yet</p> <p className="text-slate-600 dark:text-titanio text-sm mb-3">No documents yet</p>
<p className="text-slate-500 text-xs">Documents will appear here once you create them</p> <p className="text-slate-500 dark:text-titanio text-xs">Documents will appear here once you create them</p>
</div> </div>
)} )}
@@ -174,8 +174,8 @@ export const DocumentsMobileScreen: React.FC = () => {
return ( return (
<div key={doc.id} className="flex items-center justify-between border rounded-xl p-3"> <div key={doc.id} className="flex items-center justify-between border rounded-xl p-3">
<div> <div>
<div className="font-medium text-slate-800">{doc.title}</div> <div className="font-medium text-slate-800 dark:text-avus">{doc.title}</div>
<div className="text-xs text-slate-500">{doc.documentType} {vehicleLabel}</div> <div className="text-xs text-slate-500 dark:text-titanio">{doc.documentType} {vehicleLabel}</div>
</div> </div>
<div className="flex gap-2 items-center"> <div className="flex gap-2 items-center">
<Button onClick={() => navigate(`/garage/documents/${doc.id}`)}>Open</Button> <Button onClick={() => navigate(`/garage/documents/${doc.id}`)}>Open</Button>

View File

@@ -188,10 +188,16 @@ const FuelLogFormComponent: React.FC<{ onSuccess?: () => void; initial?: Partial
InputProps={{ InputProps={{
readOnly: true, readOnly: true,
sx: (theme) => ({ sx: (theme) => ({
backgroundColor: theme.palette.mode === 'dark' ? '#4C4E4D' : 'grey.50', backgroundColor: 'grey.50',
...theme.applyStyles('dark', {
backgroundColor: '#4C4E4D',
}),
'& .MuiOutlinedInput-input': { '& .MuiOutlinedInput-input': {
cursor: 'default', cursor: 'default',
color: theme.palette.mode === 'dark' ? '#F2F3F6' : 'inherit', color: 'inherit',
...theme.applyStyles('dark', {
color: '#F2F3F6',
}),
}, },
}), }),
}} }}

View File

@@ -333,7 +333,10 @@ export const StationPicker: React.FC<StationPickerProps> = ({
sx={(theme) => ({ sx={(theme) => ({
'& .MuiAutocomplete-groupLabel': { '& .MuiAutocomplete-groupLabel': {
fontWeight: 600, fontWeight: 600,
backgroundColor: theme.palette.mode === 'dark' ? '#4C4E4D' : 'grey.100', backgroundColor: 'grey.100',
...theme.applyStyles('dark', {
backgroundColor: '#4C4E4D',
}),
fontSize: '0.75rem', fontSize: '0.75rem',
textTransform: 'uppercase', textTransform: 'uppercase',
letterSpacing: '0.5px' letterSpacing: '0.5px'

View File

@@ -36,13 +36,13 @@ export const DeleteAccountModal: React.FC<DeleteAccountModalProps> = ({ isOpen,
return ( return (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4"> <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4">
<div className="bg-white rounded-lg p-6 max-w-md w-full"> <div className="bg-white dark:bg-scuro rounded-lg p-6 max-w-md w-full">
<h3 className="text-xl font-semibold text-slate-800 mb-4">Delete Account</h3> <h3 className="text-xl font-semibold text-slate-800 dark:text-avus mb-4">Delete Account</h3>
{/* Warning Alert */} {/* Warning Alert */}
<div className="mb-4 p-4 bg-amber-50 border border-amber-200 rounded-lg"> <div className="mb-4 p-4 bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-700 rounded-lg">
<p className="font-semibold text-amber-900 mb-2">30-Day Grace Period</p> <p className="font-semibold text-amber-900 dark:text-amber-200 mb-2">30-Day Grace Period</p>
<p className="text-sm text-amber-800"> <p className="text-sm text-amber-800 dark:text-amber-300">
Your account will be scheduled for deletion in 30 days. You can cancel this request at any time during 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. the grace period by logging back in.
</p> </p>
@@ -50,7 +50,7 @@ export const DeleteAccountModal: React.FC<DeleteAccountModalProps> = ({ isOpen,
{/* Confirmation Input */} {/* Confirmation Input */}
<div className="mb-6"> <div className="mb-6">
<label className="block text-sm font-medium text-slate-700 mb-1"> <label className="block text-sm font-medium text-slate-700 dark:text-avus mb-1">
Type DELETE to confirm Type DELETE to confirm
</label> </label>
<input <input
@@ -58,14 +58,14 @@ export const DeleteAccountModal: React.FC<DeleteAccountModalProps> = ({ isOpen,
value={confirmationText} value={confirmationText}
onChange={(e) => setConfirmationText(e.target.value)} onChange={(e) => setConfirmationText(e.target.value)}
placeholder="DELETE" 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' confirmationText.length > 0 && confirmationText !== 'DELETE'
? 'border-red-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 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' }} style={{ fontSize: '16px', minHeight: '44px' }}
/> />
<p className="text-xs text-slate-500 mt-1">Type the word "DELETE" (all caps) to confirm</p> <p className="text-xs text-slate-500 dark:text-titanio mt-1">Type the word "DELETE" (all caps) to confirm</p>
</div> </div>
{/* Action Buttons */} {/* Action Buttons */}
@@ -73,7 +73,7 @@ export const DeleteAccountModal: React.FC<DeleteAccountModalProps> = ({ isOpen,
<button <button
onClick={onClose} onClick={onClose}
disabled={requestDeletionMutation.isPending} disabled={requestDeletionMutation.isPending}
className="flex-1 py-2.5 px-4 bg-gray-200 text-gray-700 rounded-lg font-medium hover:bg-gray-300 transition-colors disabled:opacity-50" className="flex-1 py-2.5 px-4 bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-200 rounded-lg font-medium hover:bg-gray-300 dark:hover:bg-gray-600 transition-colors disabled:opacity-50"
style={{ minHeight: '44px' }} style={{ minHeight: '44px' }}
> >
Cancel Cancel

View File

@@ -25,9 +25,9 @@ const ToggleSwitch: React.FC<ToggleSwitchProps> = ({
}) => ( }) => (
<div className="flex items-center justify-between py-2"> <div className="flex items-center justify-between py-2">
<div> <div>
<p className="font-medium text-slate-800">{label}</p> <p className="font-medium text-slate-800 dark:text-avus">{label}</p>
{description && ( {description && (
<p className="text-sm text-slate-500">{description}</p> <p className="text-sm text-slate-500 dark:text-titanio">{description}</p>
)} )}
</div> </div>
<button <button
@@ -56,14 +56,14 @@ const Modal: React.FC<ModalProps> = ({ isOpen, onClose, title, children }) => {
if (!isOpen) return null; if (!isOpen) return null;
return ( return (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4"> <div className="fixed inset-0 bg-black bg-opacity-50 dark:bg-black/50 flex items-center justify-center z-50 p-4">
<div className="bg-white rounded-lg p-6 max-w-sm w-full"> <div className="bg-white dark:bg-scuro rounded-lg p-6 max-w-sm w-full">
<h3 className="text-lg font-semibold text-slate-800 mb-4">{title}</h3> <h3 className="text-lg font-semibold text-slate-800 dark:text-avus mb-4">{title}</h3>
{children} {children}
<div className="flex justify-end mt-4"> <div className="flex justify-end mt-4">
<button <button
onClick={onClose} onClick={onClose}
className="px-4 py-2 bg-gray-200 text-gray-700 rounded-lg font-medium" className="px-4 py-2 bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-200 rounded-lg font-medium"
> >
Close Close
</button> </button>
@@ -184,8 +184,8 @@ export const MobileSettingsScreen: React.FC = () => {
<div className="space-y-4 pb-20 p-4"> <div className="space-y-4 pb-20 p-4">
{/* Header */} {/* Header */}
<div className="text-center mb-6"> <div className="text-center mb-6">
<h1 className="text-2xl font-bold text-slate-800">Settings</h1> <h1 className="text-2xl font-bold text-slate-800 dark:text-avus">Settings</h1>
<p className="text-slate-500 mt-2">Manage your account and preferences</p> <p className="text-slate-500 dark:text-titanio mt-2">Manage your account and preferences</p>
</div> </div>
{/* Pending Deletion Banner */} {/* Pending Deletion Banner */}
@@ -195,7 +195,7 @@ export const MobileSettingsScreen: React.FC = () => {
<GlassCard padding="md"> <GlassCard padding="md">
<div> <div>
<div className="flex justify-between items-center mb-4"> <div className="flex justify-between items-center mb-4">
<h2 className="text-lg font-semibold text-slate-800">Profile</h2> <h2 className="text-lg font-semibold text-slate-800 dark:text-avus">Profile</h2>
{!isEditingProfile && !profileLoading && ( {!isEditingProfile && !profileLoading && (
<button <button
onClick={handleEditProfile} onClick={handleEditProfile}
@@ -214,21 +214,21 @@ export const MobileSettingsScreen: React.FC = () => {
) : isEditingProfile ? ( ) : isEditingProfile ? (
<div className="space-y-4"> <div className="space-y-4">
<div> <div>
<label className="block text-sm font-medium text-slate-700 mb-1"> <label className="block text-sm font-medium text-slate-700 dark:text-avus mb-1">
Email Email
</label> </label>
<input <input
type="email" type="email"
value={profile?.email || ''} value={profile?.email || ''}
disabled disabled
className="w-full px-3 py-2 border border-slate-300 rounded-lg bg-slate-100 text-slate-500" className="w-full px-3 py-2 border border-slate-300 dark:border-silverstone rounded-lg bg-slate-100 dark:bg-gray-800 text-slate-500 dark:text-gray-400"
style={{ fontSize: '16px', minHeight: '44px' }} style={{ fontSize: '16px', minHeight: '44px' }}
/> />
<p className="text-xs text-slate-500 mt-1">Email is managed by your account provider</p> <p className="text-xs text-slate-500 dark:text-titanio mt-1">Email is managed by your account provider</p>
</div> </div>
<div> <div>
<label className="block text-sm font-medium text-slate-700 mb-1"> <label className="block text-sm font-medium text-slate-700 dark:text-avus mb-1">
Display Name Display Name
</label> </label>
<input <input
@@ -236,13 +236,13 @@ export const MobileSettingsScreen: React.FC = () => {
value={editedDisplayName} value={editedDisplayName}
onChange={(e) => setEditedDisplayName(e.target.value)} onChange={(e) => setEditedDisplayName(e.target.value)}
placeholder="Enter your display name" 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' }} style={{ fontSize: '16px', minHeight: '44px' }}
/> />
</div> </div>
<div> <div>
<label className="block text-sm font-medium text-slate-700 mb-1"> <label className="block text-sm font-medium text-slate-700 dark:text-avus mb-1">
Notification Email Notification Email
</label> </label>
<input <input
@@ -250,17 +250,17 @@ export const MobileSettingsScreen: React.FC = () => {
value={editedNotificationEmail} value={editedNotificationEmail}
onChange={(e) => setEditedNotificationEmail(e.target.value)} onChange={(e) => setEditedNotificationEmail(e.target.value)}
placeholder="Leave blank to use your primary email" 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' }} style={{ fontSize: '16px', minHeight: '44px' }}
/> />
<p className="text-xs text-slate-500 mt-1">Optional: Use a different email for notifications</p> <p className="text-xs text-slate-500 dark:text-titanio mt-1">Optional: Use a different email for notifications</p>
</div> </div>
<div className="flex space-x-3 pt-2"> <div className="flex space-x-3 pt-2">
<button <button
onClick={handleCancelEdit} onClick={handleCancelEdit}
disabled={updateProfileMutation.isPending} disabled={updateProfileMutation.isPending}
className="flex-1 py-2.5 px-4 bg-gray-200 text-gray-700 rounded-lg font-medium hover:bg-gray-300 transition-colors disabled:opacity-50" className="flex-1 py-2.5 px-4 bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-200 rounded-lg font-medium hover:bg-gray-300 dark:hover:bg-gray-600 transition-colors disabled:opacity-50"
style={{ minHeight: '44px' }} style={{ minHeight: '44px' }}
> >
Cancel Cancel
@@ -294,21 +294,21 @@ export const MobileSettingsScreen: React.FC = () => {
</div> </div>
)} )}
<div className="min-w-0 flex-1"> <div className="min-w-0 flex-1">
<p className="font-medium text-slate-800 truncate"> <p className="font-medium text-slate-800 dark:text-avus truncate">
{profile?.displayName || user?.name || 'User'} {profile?.displayName || user?.name || 'User'}
</p> </p>
<p className="text-sm text-slate-500 truncate">{profile?.email || user?.email}</p> <p className="text-sm text-slate-500 dark:text-titanio truncate">{profile?.email || user?.email}</p>
</div> </div>
</div> </div>
<div className="space-y-2 pt-3 border-t border-slate-200"> <div className="space-y-2 pt-3 border-t border-slate-200 dark:border-silverstone">
<div> <div>
<p className="text-xs font-medium text-slate-500 uppercase">Display Name</p> <p className="text-xs font-medium text-slate-500 dark:text-canna uppercase">Display Name</p>
<p className="text-sm text-slate-800">{profile?.displayName || 'Not set'}</p> <p className="text-sm text-slate-800 dark:text-avus">{profile?.displayName || 'Not set'}</p>
</div> </div>
<div> <div>
<p className="text-xs font-medium text-slate-500 uppercase">Notification Email</p> <p className="text-xs font-medium text-slate-500 dark:text-canna uppercase">Notification Email</p>
<p className="text-sm text-slate-800">{profile?.notificationEmail || 'Using primary email'}</p> <p className="text-sm text-slate-800 dark:text-avus">{profile?.notificationEmail || 'Using primary email'}</p>
</div> </div>
</div> </div>
</div> </div>
@@ -319,7 +319,7 @@ export const MobileSettingsScreen: React.FC = () => {
{/* Notifications Section */} {/* Notifications Section */}
<GlassCard padding="md"> <GlassCard padding="md">
<div> <div>
<h2 className="text-lg font-semibold text-slate-800 mb-4">Notifications</h2> <h2 className="text-lg font-semibold text-slate-800 dark:text-avus mb-4">Notifications</h2>
<div className="space-y-3"> <div className="space-y-3">
<ToggleSwitch <ToggleSwitch
enabled={settings.notifications.email} enabled={settings.notifications.email}
@@ -355,7 +355,7 @@ export const MobileSettingsScreen: React.FC = () => {
{/* Appearance & Units Section */} {/* Appearance & Units Section */}
<GlassCard padding="md"> <GlassCard padding="md">
<div> <div>
<h2 className="text-lg font-semibold text-slate-800 mb-4">Appearance & Units</h2> <h2 className="text-lg font-semibold text-slate-800 dark:text-avus mb-4">Appearance & Units</h2>
<div className="space-y-4"> <div className="space-y-4">
<ToggleSwitch <ToggleSwitch
enabled={settings.darkMode} enabled={settings.darkMode}
@@ -366,8 +366,8 @@ export const MobileSettingsScreen: React.FC = () => {
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div> <div>
<p className="font-medium text-slate-800">Unit System</p> <p className="font-medium text-slate-800 dark:text-avus">Unit System</p>
<p className="text-sm text-slate-500"> <p className="text-sm text-slate-500 dark:text-titanio">
Currently using {settings.unitSystem === 'imperial' ? 'Miles, Gallons, MPG, USD' : 'Km, Liters, L/100km, EUR'} Currently using {settings.unitSystem === 'imperial' ? 'Miles, Gallons, MPG, USD' : 'Km, Liters, L/100km, EUR'}
</p> </p>
</div> </div>
@@ -385,7 +385,7 @@ export const MobileSettingsScreen: React.FC = () => {
{/* Data Management Section */} {/* Data Management Section */}
<GlassCard padding="md"> <GlassCard padding="md">
<div> <div>
<h2 className="text-lg font-semibold text-slate-800 mb-4">Data Management</h2> <h2 className="text-lg font-semibold text-slate-800 dark:text-avus mb-4">Data Management</h2>
<div className="space-y-3"> <div className="space-y-3">
<button <button
onClick={() => setShowDataExport(true)} onClick={() => setShowDataExport(true)}
@@ -393,7 +393,7 @@ export const MobileSettingsScreen: React.FC = () => {
> >
Export My Data Export My Data
</button> </button>
<p className="text-sm text-slate-500"> <p className="text-sm text-slate-500 dark:text-titanio">
Download a copy of all your vehicle and fuel data Download a copy of all your vehicle and fuel data
</p> </p>
</div> </div>
@@ -421,7 +421,7 @@ export const MobileSettingsScreen: React.FC = () => {
{!adminLoading && isAdmin && ( {!adminLoading && isAdmin && (
<GlassCard padding="md"> <GlassCard padding="md">
<div> <div>
<h2 className="text-lg font-semibold text-primary-500 mb-4">Admin Console</h2> <h2 className="text-lg font-semibold text-primary-500 dark:text-primary-400 mb-4">Admin Console</h2>
<div className="space-y-3"> <div className="space-y-3">
<button <button
onClick={() => navigateToScreen('AdminUsers')} onClick={() => navigateToScreen('AdminUsers')}
@@ -463,11 +463,11 @@ export const MobileSettingsScreen: React.FC = () => {
{/* Account Actions Section */} {/* Account Actions Section */}
<GlassCard padding="md"> <GlassCard padding="md">
<div> <div>
<h2 className="text-lg font-semibold text-slate-800 mb-4">Account Actions</h2> <h2 className="text-lg font-semibold text-slate-800 dark:text-avus mb-4">Account Actions</h2>
<div className="space-y-3"> <div className="space-y-3">
<button <button
onClick={handleLogout} onClick={handleLogout}
className="w-full py-3 px-4 bg-gray-100 text-gray-700 rounded-lg text-left font-medium hover:bg-gray-200 transition-colors" className="w-full py-3 px-4 bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-200 rounded-lg text-left font-medium hover:bg-gray-200 dark:hover:bg-gray-600 transition-colors"
> >
Sign Out Sign Out
</button> </button>
@@ -487,7 +487,7 @@ export const MobileSettingsScreen: React.FC = () => {
onClose={() => setShowDataExport(false)} onClose={() => setShowDataExport(false)}
title="Export Data" title="Export Data"
> >
<p className="text-slate-600 mb-4"> <p className="text-slate-600 dark:text-titanio mb-4">
This will create a downloadable file containing all your vehicle data, fuel logs, and preferences. This will create a downloadable file containing all your vehicle data, fuel logs, and preferences.
</p> </p>
<div className="flex space-x-3"> <div className="flex space-x-3">

View File

@@ -14,3 +14,21 @@ body {
* { * {
box-sizing: border-box; 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;
}

View File

@@ -28,7 +28,7 @@ export const GlassCard: React.FC<GlassCardProps> = ({
return ( return (
<div <div
className={clsx( className={clsx(
'rounded-3xl border border-slate-200/70 bg-white/80 shadow-sm backdrop-blur', 'rounded-3xl border border-slate-200/70 dark:border-slate-700/70 bg-white/80 dark:bg-nero/80 shadow-sm backdrop-blur',
paddings[padding], paddings[padding],
onClick && 'cursor-pointer hover:shadow-xl hover:-translate-y-0.5 transition', onClick && 'cursor-pointer hover:shadow-xl hover:-translate-y-0.5 transition',
className className

View File

@@ -15,7 +15,7 @@ export const MobileContainer: React.FC<MobileContainerProps> = ({
}) => { }) => {
return ( return (
<div className="w-full min-h-screen bg-gradient-to-br from-slate-50 via-white to-rose-50 dark:from-paper dark:via-nero dark:to-paper flex items-start justify-center p-4 md:py-6"> <div className="w-full min-h-screen bg-gradient-to-br from-slate-50 via-white to-rose-50 dark:from-paper dark:via-nero dark:to-paper flex items-start justify-center p-4 md:py-6">
<div className={`w-full max-w-[380px] min-h-screen md:min-h-[600px] md:rounded-[32px] shadow-2xl flex flex-col border-0 md:border border-slate-200/70 bg-white/90 md:bg-white/70 backdrop-blur-xl ${className}`}> <div className={`w-full max-w-[380px] min-h-screen md:min-h-[600px] md:rounded-[32px] shadow-2xl flex flex-col border-0 md:border border-slate-200/70 dark:border-slate-700/70 bg-white/90 dark:bg-nero/90 md:bg-white/70 md:dark:bg-nero/70 backdrop-blur-xl ${className}`}>
{children} {children}
</div> </div>
</div> </div>

View File

@@ -29,7 +29,7 @@ export const MobilePill: React.FC<MobilePillProps> = ({
"group h-11 rounded-2xl text-sm font-medium border transition flex items-center justify-center gap-2 backdrop-blur", "group h-11 rounded-2xl text-sm font-medium border transition flex items-center justify-center gap-2 backdrop-blur",
active active
? "text-white border-transparent shadow-lg bg-gradient-moto" ? "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 className
)} )}
> >