mirror of
https://github.com/jjbrunton/Sauci.git
synced 2026-10-31 18:19:43 +00:00
Fix premium access check and tab bar styling
This commit is contained in:
1 parent
1e4974e2a0
commit
a531f43d91
4 files changed
+114
-113
No files matched your search
+4
-4
@@ -16,10 +16,10 @@ build/
|
|||||||
.env.local
|
.env.local
|
||||||
.env.development.local
|
.env.development.local
|
||||||
.env.test.local
|
.env.test.local
|
||||||
.env.production.local
|
.env.production.local
|
||||||
apps/mobile/.env.prod
|
apps/mobile/.env.*
|
||||||
.secrets
|
.secrets
|
||||||
|
|
||||||
|
|
||||||
# Supabase
|
# Supabase
|
||||||
.supabase/
|
.supabase/
|
||||||
|
|||||||
@@ -43,11 +43,14 @@ function TabBarBackground() {
|
|||||||
// The solid rgba background in tabBarStyle provides the visual effect on Android
|
// The solid rgba background in tabBarStyle provides the visual effect on Android
|
||||||
if (Platform.OS === 'ios') {
|
if (Platform.OS === 'ios') {
|
||||||
return (
|
return (
|
||||||
<BlurView
|
<>
|
||||||
intensity={100}
|
<BlurView
|
||||||
tint="dark"
|
intensity={80}
|
||||||
style={StyleSheet.absoluteFill}
|
tint="dark"
|
||||||
/>
|
style={StyleSheet.absoluteFill}
|
||||||
|
/>
|
||||||
|
<View style={[StyleSheet.absoluteFill, { backgroundColor: 'rgba(14, 14, 17, 0.85)' }]} />
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@@ -435,7 +438,7 @@ export default function AppLayout() {
|
|||||||
tabBarBackground: () => <TabBarBackground />,
|
tabBarBackground: () => <TabBarBackground />,
|
||||||
tabBarStyle: shouldHideTabBar ? { display: 'none' } : {
|
tabBarStyle: shouldHideTabBar ? { display: 'none' } : {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
backgroundColor: 'rgba(13, 13, 26, 0.92)',
|
backgroundColor: 'rgba(14, 14, 17, 0.85)',
|
||||||
borderTopColor: 'rgba(233, 69, 96, 0.2)', // primary brand color
|
borderTopColor: 'rgba(233, 69, 96, 0.2)', // primary brand color
|
||||||
borderTopWidth: 1,
|
borderTopWidth: 1,
|
||||||
paddingTop: 8,
|
paddingTop: 8,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { useFocusEffect } from 'expo-router';
|
|||||||
import Animated, { FadeInDown } from 'react-native-reanimated';
|
import Animated, { FadeInDown } from 'react-native-reanimated';
|
||||||
import { Ionicons } from '@expo/vector-icons';
|
import { Ionicons } from '@expo/vector-icons';
|
||||||
import { BlurView } from 'expo-blur';
|
import { BlurView } from 'expo-blur';
|
||||||
import { useAuthStore, usePacksStore } from '../../src/store';
|
import { useAuthStore, usePacksStore, useSubscriptionStore } from '../../src/store';
|
||||||
import { GradientBackground } from '../../src/components/ui';
|
import { GradientBackground } from '../../src/components/ui';
|
||||||
import { Paywall } from '../../src/components/paywall';
|
import { Paywall } from '../../src/components/paywall';
|
||||||
import { CompactHeader, ContentRow } from '../../src/components/discovery';
|
import { CompactHeader, ContentRow } from '../../src/components/discovery';
|
||||||
@@ -18,61 +18,63 @@ function groupPacksByCategory(
|
|||||||
packs: QuestionPack[],
|
packs: QuestionPack[],
|
||||||
categories: Category[]
|
categories: Category[]
|
||||||
): { category: Category; packs: QuestionPack[] }[] {
|
): { category: Category; packs: QuestionPack[] }[] {
|
||||||
const categoryMap = new Map<string, QuestionPack[]>();
|
const categoryMap = new Map<string, QuestionPack[]>();
|
||||||
const uncategorized: QuestionPack[] = [];
|
const uncategorized: QuestionPack[] = [];
|
||||||
|
|
||||||
// Initialize map with empty arrays for each category
|
// Initialize map with empty arrays for each category
|
||||||
categories.forEach((cat) => {
|
categories.forEach((cat) => {
|
||||||
categoryMap.set(cat.id, []);
|
categoryMap.set(cat.id, []);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Group packs
|
// Group packs
|
||||||
packs.forEach((pack) => {
|
packs.forEach((pack) => {
|
||||||
if (pack.category_id && categoryMap.has(pack.category_id)) {
|
if (pack.category_id && categoryMap.has(pack.category_id)) {
|
||||||
categoryMap.get(pack.category_id)!.push(pack);
|
categoryMap.get(pack.category_id)!.push(pack);
|
||||||
} else {
|
} else {
|
||||||
uncategorized.push(pack);
|
uncategorized.push(pack);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Build result array maintaining category sort order
|
// Build result array maintaining category sort order
|
||||||
const result: { category: Category; packs: QuestionPack[] }[] = [];
|
const result: { category: Category; packs: QuestionPack[] }[] = [];
|
||||||
|
|
||||||
categories.forEach((cat) => {
|
categories.forEach((cat) => {
|
||||||
const categoryPacks = categoryMap.get(cat.id) || [];
|
const categoryPacks = categoryMap.get(cat.id) || [];
|
||||||
if (categoryPacks.length > 0) {
|
if (categoryPacks.length > 0) {
|
||||||
result.push({ category: cat, packs: categoryPacks });
|
result.push({ category: cat, packs: categoryPacks });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add uncategorized at the end if any
|
// Add uncategorized at the end if any
|
||||||
if (uncategorized.length > 0) {
|
if (uncategorized.length > 0) {
|
||||||
result.push({
|
result.push({
|
||||||
category: {
|
category: {
|
||||||
id: 'uncategorized',
|
id: 'uncategorized',
|
||||||
name: 'More',
|
name: 'More',
|
||||||
description: null,
|
description: null,
|
||||||
icon: 'ellipsis-horizontal',
|
icon: 'ellipsis-horizontal',
|
||||||
color: null,
|
color: null,
|
||||||
sort_order: 999,
|
sort_order: 999,
|
||||||
created_at: '',
|
created_at: '',
|
||||||
is_public: true,
|
is_public: true,
|
||||||
},
|
},
|
||||||
packs: uncategorized,
|
packs: uncategorized,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function DiscoveryScreen() {
|
export default function DiscoveryScreen() {
|
||||||
const { user, partner, couple } = useAuthStore();
|
const { user, partner, couple } = useAuthStore();
|
||||||
const { packs, categories, fetchPacks, getPackProgress } = usePacksStore();
|
const { packs, categories, fetchPacks, getPackProgress } = usePacksStore();
|
||||||
|
const { subscription } = useSubscriptionStore();
|
||||||
const { width } = useWindowDimensions();
|
const { width } = useWindowDimensions();
|
||||||
const [showPaywall, setShowPaywall] = useState(false);
|
const [showPaywall, setShowPaywall] = useState(false);
|
||||||
const [headerHeight, setHeaderHeight] = useState(130);
|
const [headerHeight, setHeaderHeight] = useState(130);
|
||||||
|
|
||||||
const isPremiumUser = user?.is_premium ?? false;
|
// Check all sources of premium access: user flag, partner flag, or active subscription
|
||||||
|
const isPremiumUser = user?.is_premium || partner?.is_premium || subscription.isProUser;
|
||||||
const isWideScreen = width > MAX_CONTENT_WIDTH;
|
const isWideScreen = width > MAX_CONTENT_WIDTH;
|
||||||
|
|
||||||
// Refresh data when screen gains focus
|
// Refresh data when screen gains focus
|
||||||
@@ -159,51 +161,51 @@ export default function DiscoveryScreen() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
},
|
},
|
||||||
contentContainer: {
|
contentContainer: {
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
paddingBottom: Platform.OS === 'ios' ? 100 : 80,
|
paddingBottom: Platform.OS === 'ios' ? 100 : 80,
|
||||||
},
|
},
|
||||||
contentContainerWide: {
|
contentContainerWide: {
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
},
|
},
|
||||||
innerContainer: {
|
innerContainer: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
width: '100%',
|
width: '100%',
|
||||||
},
|
},
|
||||||
innerContainerWide: {
|
innerContainerWide: {
|
||||||
maxWidth: MAX_CONTENT_WIDTH,
|
maxWidth: MAX_CONTENT_WIDTH,
|
||||||
},
|
},
|
||||||
emptyState: {
|
emptyState: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
paddingHorizontal: spacing.xl,
|
paddingHorizontal: spacing.xl,
|
||||||
paddingVertical: spacing.xxl,
|
paddingVertical: spacing.xxl,
|
||||||
},
|
},
|
||||||
emptyIcon: {
|
emptyIcon: {
|
||||||
width: 80,
|
width: 80,
|
||||||
height: 80,
|
height: 80,
|
||||||
borderRadius: 40,
|
borderRadius: 40,
|
||||||
backgroundColor: 'rgba(233, 69, 96, 0.1)',
|
backgroundColor: 'rgba(233, 69, 96, 0.1)',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
marginBottom: spacing.lg,
|
marginBottom: spacing.lg,
|
||||||
},
|
},
|
||||||
emptyTitle: {
|
emptyTitle: {
|
||||||
...typography.title3,
|
...typography.title3,
|
||||||
color: colors.text,
|
color: colors.text,
|
||||||
marginBottom: spacing.sm,
|
marginBottom: spacing.sm,
|
||||||
},
|
},
|
||||||
emptySubtitle: {
|
emptySubtitle: {
|
||||||
...typography.body,
|
...typography.body,
|
||||||
color: colors.textSecondary,
|
color: colors.textSecondary,
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
},
|
},
|
||||||
bottomSpacer: {
|
bottomSpacer: {
|
||||||
height: spacing.lg,
|
height: spacing.lg,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1267,8 +1267,6 @@ export default function SwipeScreen() {
|
|||||||
</Animated.View>
|
</Animated.View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
{/* Spacer to balance header when back button is shown */}
|
|
||||||
{(packId || mode === 'pending') && <View style={styles.headerSpacer} />}
|
|
||||||
</View>
|
</View>
|
||||||
</Animated.View>
|
</Animated.View>
|
||||||
|
|
||||||
@@ -1370,11 +1368,9 @@ const styles = StyleSheet.create({
|
|||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
},
|
},
|
||||||
backButton: {
|
backButton: {
|
||||||
|
position: 'absolute',
|
||||||
|
left: 0,
|
||||||
padding: spacing.sm,
|
padding: spacing.sm,
|
||||||
marginRight: spacing.sm,
|
|
||||||
},
|
|
||||||
headerSpacer: {
|
|
||||||
width: 40, // Match back button width for centering
|
|
||||||
},
|
},
|
||||||
progressContainer: {
|
progressContainer: {
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
|
|||||||
Reference in new issue
Block a user