fix: match import button style to export button (refs #26)
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 2m39s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 37s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped

Desktop changes:
- Replace ImportButton component with MUI Button matching Export style
- Use hidden file input with validation
- Dark red/maroon button with consistent styling

Mobile changes:
- Update both Import and Export buttons to use primary-500 style
- Consistent dark primary button appearance
- Maintains 44px touch target requirement

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Eric Gullickson
2026-01-11 20:23:56 -06:00
parent 5648f4c3d0
commit 566deae5af
3 changed files with 50 additions and 5 deletions

View File

@@ -57,7 +57,7 @@ export const ImportButton: React.FC<ImportButtonProps> = ({
<button <button
onClick={handleButtonClick} onClick={handleButtonClick}
disabled={disabled} disabled={disabled}
className="w-full text-left p-3 bg-primary-50 text-primary-700 rounded-lg font-medium hover:bg-primary-100 transition-colors disabled:opacity-50 dark:bg-primary-900/20 dark:text-primary-300 dark:hover:bg-primary-900/30" className="w-full text-left p-3 bg-primary-500 text-white rounded-lg font-medium hover:bg-primary-600 transition-colors disabled:opacity-50 dark:bg-primary-600 dark:hover:bg-primary-700"
style={{ minHeight: '44px' }} style={{ minHeight: '44px' }}
> >
Import My Data Import My Data

View File

@@ -459,7 +459,7 @@ export const MobileSettingsScreen: React.FC = () => {
</p> </p>
<button <button
onClick={() => setShowDataExport(true)} onClick={() => setShowDataExport(true)}
className="w-full text-left p-3 bg-primary-50 text-primary-700 rounded-lg font-medium hover:bg-primary-100 transition-colors dark:bg-primary-900/20 dark:text-primary-300 dark:hover:bg-primary-900/30" className="w-full text-left p-3 bg-primary-500 text-white rounded-lg font-medium hover:bg-primary-600 transition-colors disabled:opacity-50 dark:bg-primary-600 dark:hover:bg-primary-700"
style={{ minHeight: '44px' }} style={{ minHeight: '44px' }}
> >
Export My Data Export My Data

View File

@@ -14,8 +14,8 @@ import { useVehicles } from '../features/vehicles/hooks/useVehicles';
import { useTheme } from '../shared-minimal/theme/ThemeContext'; import { useTheme } from '../shared-minimal/theme/ThemeContext';
import { DeleteAccountDialog } from '../features/settings/components/DeleteAccountDialog'; import { DeleteAccountDialog } from '../features/settings/components/DeleteAccountDialog';
import { PendingDeletionBanner } from '../features/settings/components/PendingDeletionBanner'; import { PendingDeletionBanner } from '../features/settings/components/PendingDeletionBanner';
import { ImportButton } from '../features/settings/components/ImportButton';
import { ImportDialog } from '../features/settings/components/ImportDialog'; import { ImportDialog } from '../features/settings/components/ImportDialog';
import toast from 'react-hot-toast';
import { import {
Box, Box,
Typography, Typography,
@@ -68,6 +68,7 @@ export const SettingsPage: React.FC = () => {
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
const [importDialogOpen, setImportDialogOpen] = useState(false); const [importDialogOpen, setImportDialogOpen] = useState(false);
const [selectedFile, setSelectedFile] = useState<File | null>(null); const [selectedFile, setSelectedFile] = useState<File | null>(null);
const fileInputRef = React.useRef<HTMLInputElement>(null);
const exportMutation = useExportUserData(); const exportMutation = useExportUserData();
// Initialize edit form when profile loads or edit mode starts // Initialize edit form when profile loads or edit mode starts
@@ -116,9 +117,32 @@ export const SettingsPage: React.FC = () => {
} }
}; };
const handleImportFileSelected = (file: File) => { const handleImportClick = () => {
fileInputRef.current?.click();
};
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0];
if (!file) return;
// Validate file extension
if (!file.name.endsWith('.tar.gz')) {
toast.error('Please select a .tar.gz file');
return;
}
// Validate file size (max 500MB)
const maxSize = 500 * 1024 * 1024;
if (file.size > maxSize) {
toast.error('File size exceeds 500MB limit');
return;
}
setSelectedFile(file); setSelectedFile(file);
setImportDialogOpen(true); setImportDialogOpen(true);
// Reset input so same file can be selected again
event.target.value = '';
}; };
const handleImportClose = () => { const handleImportClose = () => {
@@ -463,7 +487,28 @@ export const SettingsPage: React.FC = () => {
secondary="Upload and restore your vehicle data from a backup" secondary="Upload and restore your vehicle data from a backup"
/> />
<ListItemSecondaryAction> <ListItemSecondaryAction>
<ImportButton onFileSelected={handleImportFileSelected} /> <input
ref={fileInputRef}
type="file"
accept=".tar.gz"
onChange={handleFileChange}
style={{ display: 'none' }}
aria-label="Select import file"
/>
<MuiButton
variant="contained"
size="small"
onClick={handleImportClick}
sx={{
backgroundColor: 'primary.main',
color: 'primary.contrastText',
'&:hover': {
backgroundColor: 'primary.dark'
}
}}
>
Import
</MuiButton>
</ListItemSecondaryAction> </ListItemSecondaryAction>
</ListItem> </ListItem>
<Divider /> <Divider />