fix: post Dark mode fixes
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="color-scheme" content="light dark">
|
||||
<title>MotoVaultPro</title>
|
||||
<!-- Runtime config MUST load synchronously before any module scripts -->
|
||||
<script src="/config.js"></script>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import React from 'react';
|
||||
import { useAuth0 } from '@auth0/auth0-react';
|
||||
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 LocalGasStationRoundedIcon from '@mui/icons-material/LocalGasStationRounded';
|
||||
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 { sidebarOpen, toggleSidebar, setSidebarOpen } = useAppStore();
|
||||
const location = useLocation();
|
||||
const theme = useTheme();
|
||||
|
||||
// Sync theme preference with backend
|
||||
useThemeSync();
|
||||
@@ -128,14 +127,17 @@ export const Layout: React.FC<LayoutProps> = ({ children, mobileMode = false })
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
backgroundColor: theme.palette.mode === 'light' ? 'primary.main' : 'transparent',
|
||||
sx={(theme) => ({
|
||||
backgroundColor: 'primary.main',
|
||||
...theme.applyStyles('dark', {
|
||||
backgroundColor: 'transparent',
|
||||
}),
|
||||
borderRadius: 1,
|
||||
px: 1,
|
||||
py: 0.5,
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center'
|
||||
}}
|
||||
})}
|
||||
>
|
||||
<img
|
||||
src="/images/logos/motovaultpro-title-slogan.png"
|
||||
|
||||
@@ -610,7 +610,7 @@ export const AdminBackupMobileScreen: React.FC = () => {
|
||||
|
||||
{showRestoreConfirm && (
|
||||
<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>
|
||||
<div className="bg-red-50 border border-red-200 rounded-lg p-3 mb-4">
|
||||
<p className="text-xs text-red-800">
|
||||
@@ -988,7 +988,7 @@ export const AdminBackupMobileScreen: React.FC = () => {
|
||||
{/* Delete Backup Confirmation Modal */}
|
||||
{showDeleteBackupConfirm && (
|
||||
<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>
|
||||
<p className="text-sm text-slate-600 mb-4">
|
||||
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 && (
|
||||
<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>
|
||||
<p className="text-sm text-slate-600 mb-4">
|
||||
Are you sure you want to delete "{selectedSchedule?.name}"? This action cannot be
|
||||
|
||||
@@ -379,14 +379,14 @@ export const AdminCatalogMobileScreen: React.FC = () => {
|
||||
{menuOpen && (
|
||||
<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-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()}
|
||||
>
|
||||
<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
|
||||
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' }}
|
||||
>
|
||||
<Close />
|
||||
@@ -396,7 +396,7 @@ export const AdminCatalogMobileScreen: React.FC = () => {
|
||||
<button
|
||||
onClick={handleImportClick}
|
||||
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' }}
|
||||
>
|
||||
<FileUpload />
|
||||
@@ -406,7 +406,7 @@ export const AdminCatalogMobileScreen: React.FC = () => {
|
||||
<button
|
||||
onClick={handleExport}
|
||||
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' }}
|
||||
>
|
||||
<FileDownload />
|
||||
@@ -415,7 +415,7 @@ export const AdminCatalogMobileScreen: React.FC = () => {
|
||||
|
||||
<button
|
||||
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' }}
|
||||
>
|
||||
Cancel
|
||||
@@ -427,9 +427,9 @@ export const AdminCatalogMobileScreen: React.FC = () => {
|
||||
{/* Delete Confirmation Sheet */}
|
||||
{deleteSheet.open && deleteSheet.item && (
|
||||
<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">
|
||||
<h2 className="text-xl font-bold text-slate-800">Delete Configuration?</h2>
|
||||
<p className="text-slate-600">
|
||||
<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 dark:text-avus">Delete Configuration?</h2>
|
||||
<p className="text-slate-600 dark:text-titanio">
|
||||
Are you sure you want to delete{' '}
|
||||
<strong>
|
||||
{deleteSheet.item.year} {deleteSheet.item.make} {deleteSheet.item.model}{' '}
|
||||
@@ -441,7 +441,7 @@ export const AdminCatalogMobileScreen: React.FC = () => {
|
||||
<button
|
||||
onClick={() => 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) && (
|
||||
<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">
|
||||
<h2 className="text-xl font-bold text-slate-800">
|
||||
{importResult ? 'Import Results' : 'Import Preview'}
|
||||
|
||||
@@ -238,7 +238,7 @@ export const AdminEmailTemplatesMobileScreen: React.FC = () => {
|
||||
{editingTemplate.variables.map((variable) => (
|
||||
<span
|
||||
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}}}`}
|
||||
</span>
|
||||
@@ -250,7 +250,7 @@ export const AdminEmailTemplatesMobileScreen: React.FC = () => {
|
||||
<div className="flex gap-2 pt-2">
|
||||
<button
|
||||
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
|
||||
</button>
|
||||
|
||||
@@ -37,8 +37,8 @@ const Modal: React.FC<ModalProps> = ({ isOpen, onClose, title, children, actions
|
||||
|
||||
return (
|
||||
<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">
|
||||
<h3 className="text-lg font-semibold text-slate-800 mb-4">{title}</h3>
|
||||
<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 dark:text-avus mb-4">{title}</h3>
|
||||
{children}
|
||||
<div className="flex justify-end gap-2 mt-4">
|
||||
{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 && (
|
||||
<button
|
||||
@@ -378,7 +378,7 @@ export const AdminUsersMobileScreen: React.FC = () => {
|
||||
<select
|
||||
value={params.tier || ''}
|
||||
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="free">Free</option>
|
||||
@@ -393,7 +393,7 @@ export const AdminUsersMobileScreen: React.FC = () => {
|
||||
<select
|
||||
value={params.status || '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="active">Active</option>
|
||||
|
||||
@@ -114,7 +114,7 @@ export const VerifyEmailPage: React.FC = () => {
|
||||
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="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="mx-auto w-16 h-16 bg-primary-100 rounded-full flex items-center justify-center mb-4">
|
||||
<svg
|
||||
@@ -131,8 +131,8 @@ export const VerifyEmailPage: React.FC = () => {
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<h1 className="text-2xl font-bold text-gray-800 mb-2">Check Your Email</h1>
|
||||
<p className="text-gray-600">
|
||||
<h1 className="text-2xl font-bold text-gray-800 dark:text-avus mb-2">Check Your Email</h1>
|
||||
<p className="text-gray-600 dark:text-titanio">
|
||||
We've sent a verification link to
|
||||
</p>
|
||||
{email && (
|
||||
@@ -143,7 +143,7 @@ export const VerifyEmailPage: React.FC = () => {
|
||||
</div>
|
||||
|
||||
<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>Once verified, you can log in to complete your profile setup.</p>
|
||||
</div>
|
||||
|
||||
@@ -56,8 +56,8 @@ export const DocumentsMobileScreen: React.FC = () => {
|
||||
<div className="space-y-4">
|
||||
<GlassCard>
|
||||
<div className="p-4">
|
||||
<h2 className="text-lg font-semibold text-slate-800 mb-2">Documents</h2>
|
||||
<div className="text-slate-500 py-6 text-center">Loading...</div>
|
||||
<h2 className="text-lg font-semibold text-slate-800 dark:text-avus mb-2">Documents</h2>
|
||||
<div className="text-slate-500 dark:text-titanio py-6 text-center">Loading...</div>
|
||||
</div>
|
||||
</GlassCard>
|
||||
</div>
|
||||
@@ -77,8 +77,8 @@ export const DocumentsMobileScreen: React.FC = () => {
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<h3 className="text-lg font-semibold text-slate-800 mb-2">Login Required</h3>
|
||||
<p className="text-slate-600 text-sm mb-4">Please log in to view your documents</p>
|
||||
<h3 className="text-lg font-semibold text-slate-800 dark:text-avus mb-2">Login Required</h3>
|
||||
<p className="text-slate-600 dark:text-titanio text-sm mb-4">Please log in to view your documents</p>
|
||||
<button
|
||||
onClick={() => 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 = () => {
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<h3 className="text-lg font-semibold text-slate-800 mb-2">Session Expired</h3>
|
||||
<p className="text-slate-600 text-sm mb-4">Your session has expired. Please log in again.</p>
|
||||
<h3 className="text-lg font-semibold text-slate-800 dark:text-avus mb-2">Session Expired</h3>
|
||||
<p className="text-slate-600 dark:text-titanio text-sm mb-4">Your session has expired. Please log in again.</p>
|
||||
<button
|
||||
onClick={() => 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 = () => {
|
||||
<AddDocumentDialog open={isAddOpen} onClose={() => setIsAddOpen(false)} />
|
||||
<GlassCard>
|
||||
<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">
|
||||
<Button onClick={() => setIsAddOpen(true)} className="min-h-[44px]">Add Document</Button>
|
||||
</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 && (
|
||||
<div className="py-6 text-center">
|
||||
@@ -162,8 +162,8 @@ export const DocumentsMobileScreen: React.FC = () => {
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-slate-600 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-600 dark:text-titanio text-sm mb-3">No documents yet</p>
|
||||
<p className="text-slate-500 dark:text-titanio text-xs">Documents will appear here once you create them</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -174,8 +174,8 @@ export const DocumentsMobileScreen: React.FC = () => {
|
||||
return (
|
||||
<div key={doc.id} className="flex items-center justify-between border rounded-xl p-3">
|
||||
<div>
|
||||
<div className="font-medium text-slate-800">{doc.title}</div>
|
||||
<div className="text-xs text-slate-500">{doc.documentType} • {vehicleLabel}</div>
|
||||
<div className="font-medium text-slate-800 dark:text-avus">{doc.title}</div>
|
||||
<div className="text-xs text-slate-500 dark:text-titanio">{doc.documentType} • {vehicleLabel}</div>
|
||||
</div>
|
||||
<div className="flex gap-2 items-center">
|
||||
<Button onClick={() => navigate(`/garage/documents/${doc.id}`)}>Open</Button>
|
||||
|
||||
@@ -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',
|
||||
}),
|
||||
},
|
||||
}),
|
||||
}}
|
||||
|
||||
@@ -333,7 +333,10 @@ export const StationPicker: React.FC<StationPickerProps> = ({
|
||||
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'
|
||||
|
||||
@@ -36,13 +36,13 @@ export const DeleteAccountModal: React.FC<DeleteAccountModalProps> = ({ isOpen,
|
||||
|
||||
return (
|
||||
<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">
|
||||
<h3 className="text-xl font-semibold text-slate-800 mb-4">Delete Account</h3>
|
||||
<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 dark:text-avus mb-4">Delete Account</h3>
|
||||
|
||||
{/* Warning Alert */}
|
||||
<div className="mb-4 p-4 bg-amber-50 border border-amber-200 rounded-lg">
|
||||
<p className="font-semibold text-amber-900 mb-2">30-Day Grace Period</p>
|
||||
<p className="text-sm text-amber-800">
|
||||
<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 dark:text-amber-200 mb-2">30-Day Grace Period</p>
|
||||
<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
|
||||
the grace period by logging back in.
|
||||
</p>
|
||||
@@ -50,7 +50,7 @@ export const DeleteAccountModal: React.FC<DeleteAccountModalProps> = ({ isOpen,
|
||||
|
||||
{/* Confirmation Input */}
|
||||
<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
|
||||
</label>
|
||||
<input
|
||||
@@ -58,14 +58,14 @@ export const DeleteAccountModal: React.FC<DeleteAccountModalProps> = ({ 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' }}
|
||||
/>
|
||||
<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>
|
||||
|
||||
{/* Action Buttons */}
|
||||
@@ -73,7 +73,7 @@ export const DeleteAccountModal: React.FC<DeleteAccountModalProps> = ({ isOpen,
|
||||
<button
|
||||
onClick={onClose}
|
||||
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' }}
|
||||
>
|
||||
Cancel
|
||||
|
||||
@@ -25,9 +25,9 @@ const ToggleSwitch: React.FC<ToggleSwitchProps> = ({
|
||||
}) => (
|
||||
<div className="flex items-center justify-between py-2">
|
||||
<div>
|
||||
<p className="font-medium text-slate-800">{label}</p>
|
||||
<p className="font-medium text-slate-800 dark:text-avus">{label}</p>
|
||||
{description && (
|
||||
<p className="text-sm text-slate-500">{description}</p>
|
||||
<p className="text-sm text-slate-500 dark:text-titanio">{description}</p>
|
||||
)}
|
||||
</div>
|
||||
<button
|
||||
@@ -56,14 +56,14 @@ const Modal: React.FC<ModalProps> = ({ isOpen, onClose, title, children }) => {
|
||||
if (!isOpen) return null;
|
||||
|
||||
return (
|
||||
<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">
|
||||
<h3 className="text-lg font-semibold text-slate-800 mb-4">{title}</h3>
|
||||
<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 dark:bg-scuro rounded-lg p-6 max-w-sm w-full">
|
||||
<h3 className="text-lg font-semibold text-slate-800 dark:text-avus mb-4">{title}</h3>
|
||||
{children}
|
||||
<div className="flex justify-end mt-4">
|
||||
<button
|
||||
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
|
||||
</button>
|
||||
@@ -184,8 +184,8 @@ export const MobileSettingsScreen: React.FC = () => {
|
||||
<div className="space-y-4 pb-20 p-4">
|
||||
{/* Header */}
|
||||
<div className="text-center mb-6">
|
||||
<h1 className="text-2xl font-bold text-slate-800">Settings</h1>
|
||||
<p className="text-slate-500 mt-2">Manage your account and preferences</p>
|
||||
<h1 className="text-2xl font-bold text-slate-800 dark:text-avus">Settings</h1>
|
||||
<p className="text-slate-500 dark:text-titanio mt-2">Manage your account and preferences</p>
|
||||
</div>
|
||||
|
||||
{/* Pending Deletion Banner */}
|
||||
@@ -195,7 +195,7 @@ export const MobileSettingsScreen: React.FC = () => {
|
||||
<GlassCard padding="md">
|
||||
<div>
|
||||
<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 && (
|
||||
<button
|
||||
onClick={handleEditProfile}
|
||||
@@ -214,21 +214,21 @@ export const MobileSettingsScreen: React.FC = () => {
|
||||
) : isEditingProfile ? (
|
||||
<div className="space-y-4">
|
||||
<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
|
||||
</label>
|
||||
<input
|
||||
type="email"
|
||||
value={profile?.email || ''}
|
||||
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' }}
|
||||
/>
|
||||
<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>
|
||||
<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
|
||||
</label>
|
||||
<input
|
||||
@@ -236,13 +236,13 @@ export const MobileSettingsScreen: React.FC = () => {
|
||||
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' }}
|
||||
/>
|
||||
</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
|
||||
</label>
|
||||
<input
|
||||
@@ -250,17 +250,17 @@ export const MobileSettingsScreen: React.FC = () => {
|
||||
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' }}
|
||||
/>
|
||||
<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 className="flex space-x-3 pt-2">
|
||||
<button
|
||||
onClick={handleCancelEdit}
|
||||
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' }}
|
||||
>
|
||||
Cancel
|
||||
@@ -294,21 +294,21 @@ export const MobileSettingsScreen: React.FC = () => {
|
||||
</div>
|
||||
)}
|
||||
<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'}
|
||||
</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 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>
|
||||
<p className="text-xs font-medium text-slate-500 uppercase">Display Name</p>
|
||||
<p className="text-sm text-slate-800">{profile?.displayName || 'Not set'}</p>
|
||||
<p className="text-xs font-medium text-slate-500 dark:text-canna uppercase">Display Name</p>
|
||||
<p className="text-sm text-slate-800 dark:text-avus">{profile?.displayName || 'Not set'}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-xs font-medium text-slate-500 uppercase">Notification Email</p>
|
||||
<p className="text-sm text-slate-800">{profile?.notificationEmail || 'Using primary 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 dark:text-avus">{profile?.notificationEmail || 'Using primary email'}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -319,7 +319,7 @@ export const MobileSettingsScreen: React.FC = () => {
|
||||
{/* Notifications Section */}
|
||||
<GlassCard padding="md">
|
||||
<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">
|
||||
<ToggleSwitch
|
||||
enabled={settings.notifications.email}
|
||||
@@ -355,7 +355,7 @@ export const MobileSettingsScreen: React.FC = () => {
|
||||
{/* Appearance & Units Section */}
|
||||
<GlassCard padding="md">
|
||||
<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">
|
||||
<ToggleSwitch
|
||||
enabled={settings.darkMode}
|
||||
@@ -366,8 +366,8 @@ export const MobileSettingsScreen: React.FC = () => {
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<p className="font-medium text-slate-800">Unit System</p>
|
||||
<p className="text-sm text-slate-500">
|
||||
<p className="font-medium text-slate-800 dark:text-avus">Unit System</p>
|
||||
<p className="text-sm text-slate-500 dark:text-titanio">
|
||||
Currently using {settings.unitSystem === 'imperial' ? 'Miles, Gallons, MPG, USD' : 'Km, Liters, L/100km, EUR'}
|
||||
</p>
|
||||
</div>
|
||||
@@ -385,7 +385,7 @@ export const MobileSettingsScreen: React.FC = () => {
|
||||
{/* Data Management Section */}
|
||||
<GlassCard padding="md">
|
||||
<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">
|
||||
<button
|
||||
onClick={() => setShowDataExport(true)}
|
||||
@@ -393,7 +393,7 @@ export const MobileSettingsScreen: React.FC = () => {
|
||||
>
|
||||
Export My Data
|
||||
</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
|
||||
</p>
|
||||
</div>
|
||||
@@ -421,7 +421,7 @@ export const MobileSettingsScreen: React.FC = () => {
|
||||
{!adminLoading && isAdmin && (
|
||||
<GlassCard padding="md">
|
||||
<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">
|
||||
<button
|
||||
onClick={() => navigateToScreen('AdminUsers')}
|
||||
@@ -463,11 +463,11 @@ export const MobileSettingsScreen: React.FC = () => {
|
||||
{/* Account Actions Section */}
|
||||
<GlassCard padding="md">
|
||||
<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">
|
||||
<button
|
||||
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
|
||||
</button>
|
||||
@@ -487,7 +487,7 @@ export const MobileSettingsScreen: React.FC = () => {
|
||||
onClose={() => setShowDataExport(false)}
|
||||
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.
|
||||
</p>
|
||||
<div className="flex space-x-3">
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -28,7 +28,7 @@ export const GlassCard: React.FC<GlassCardProps> = ({
|
||||
return (
|
||||
<div
|
||||
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],
|
||||
onClick && 'cursor-pointer hover:shadow-xl hover:-translate-y-0.5 transition',
|
||||
className
|
||||
|
||||
@@ -15,7 +15,7 @@ export const MobileContainer: React.FC<MobileContainerProps> = ({
|
||||
}) => {
|
||||
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 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}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -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",
|
||||
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
|
||||
)}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user