feat: Accept Payments - Stripe Integration with User Tiers (#55) #56

Merged
egullickson merged 17 commits from issue-55-stripe-integration into main 2026-01-19 02:52:25 +00:00
Showing only changes of commit 26f9306d6b - Show all commits

View File

@@ -11,6 +11,7 @@ import { useAdminAccess } from '../core/auth/useAdminAccess';
import { useProfile, useUpdateProfile } from '../features/settings/hooks/useProfile';
import { useExportUserData } from '../features/settings/hooks/useExportUserData';
import { useVehicles } from '../features/vehicles/hooks/useVehicles';
import { useSubscription } from '../features/subscription/hooks/useSubscription';
import { useTheme } from '../shared-minimal/theme/ThemeContext';
import { DeleteAccountDialog } from '../features/settings/components/DeleteAccountDialog';
import { PendingDeletionBanner } from '../features/settings/components/PendingDeletionBanner';
@@ -32,7 +33,8 @@ import {
MenuItem,
FormControl,
TextField,
CircularProgress
CircularProgress,
Chip
} from '@mui/material';
import AccountCircleIcon from '@mui/icons-material/AccountCircle';
import NotificationsIcon from '@mui/icons-material/Notifications';
@@ -41,6 +43,7 @@ import SecurityIcon from '@mui/icons-material/Security';
import StorageIcon from '@mui/icons-material/Storage';
import AdminPanelSettingsIcon from '@mui/icons-material/AdminPanelSettings';
import DirectionsCarIcon from '@mui/icons-material/DirectionsCar';
import CreditCardIcon from '@mui/icons-material/CreditCard';
import EditIcon from '@mui/icons-material/Edit';
import SaveIcon from '@mui/icons-material/Save';
import CancelIcon from '@mui/icons-material/Cancel';
@@ -62,6 +65,11 @@ export const SettingsPage: React.FC = () => {
// Vehicles state (for My Vehicles section)
const { data: vehicles, isLoading: vehiclesLoading } = useVehicles();
// Subscription state
const { data: subscriptionData, isLoading: subscriptionLoading } = useSubscription();
const subscription = subscriptionData?.data;
const [isEditingProfile, setIsEditingProfile] = useState(false);
const [editedDisplayName, setEditedDisplayName] = useState('');
const [editedNotificationEmail, setEditedNotificationEmail] = useState('');
@@ -378,19 +386,78 @@ export const SettingsPage: React.FC = () => {
)}
</Card>
{/* Subscription Section */}
<Card>
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 3 }}>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
<CreditCardIcon color="primary" />
<Typography variant="h6" sx={{ fontWeight: 600 }}>
Subscription
</Typography>
</Box>
<MuiButton
variant="contained"
size="small"
onClick={() => navigate('/garage/settings/subscription')}
sx={{
backgroundColor: 'primary.main',
color: 'primary.contrastText',
'&:hover': {
backgroundColor: 'primary.dark'
}
}}
>
Manage
</MuiButton>
</Box>
{subscriptionLoading ? (
<Box sx={{ display: 'flex', justifyContent: 'center', py: 3 }}>
<CircularProgress size={24} />
</Box>
) : (
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
<Typography variant="body1" sx={{ fontWeight: 500 }}>
Current Plan:
</Typography>
<Chip
label={(subscription?.tier || 'free').toUpperCase()}
color="primary"
size="small"
/>
{subscription?.status && subscription.status !== 'active' && (
<Chip
label={subscription.status.replace('_', ' ')}
color={subscription.status === 'past_due' ? 'warning' : 'error'}
size="small"
/>
)}
</Box>
<Typography variant="body2" color="text.secondary">
{subscription?.tier === 'free'
? 'Upgrade to Pro or Enterprise for more features and vehicle slots.'
: subscription?.tier === 'pro'
? 'Pro plan with up to 5 vehicles and full features.'
: 'Enterprise plan with unlimited vehicles and all features.'}
</Typography>
</Box>
)}
</Card>
{/* Notifications Section */}
<Card>
<Typography variant="h6" sx={{ fontWeight: 600, mb: 3 }}>
Notifications
</Typography>
<List disablePadding>
<ListItem>
<ListItemIcon>
<NotificationsIcon />
</ListItemIcon>
<ListItemText
primary="Push Notifications"
<ListItemText
primary="Push Notifications"
secondary="Receive notifications about your vehicles"
/>
<ListItemSecondaryAction>