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
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:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 />
|
||||||
|
|||||||
Reference in New Issue
Block a user